Wbcom Designs WP Career Board Docs
Back to product Buy Now

Getting Started

Install, set up, and configure WP Career Board.

Introduction to WP Career Board

WP Career Board is a complete job board plugin for WordPress built natively on the WordPress Interactivity API. It lets you launch a full-featured job marketplace on any WordPress site - no shortcodes, no page reloads, no jQuery.

WP Career Board - Job Board Overview

What You Get

For your site visitors:

  • A fast, reactive job board that updates without page reloads
  • Search and filter jobs by keyword, category, job type, location, and experience level
  • Bookmark jobs to apply later
  • Full job detail pages with company information

For employers:

  • Self-service job posting with a guided multi-step form
  • Employer dashboard to manage all posted jobs and applications
  • Company profile page visible to all candidates

For candidates:

  • Candidate dashboard to track all applications in one place
  • Saved jobs list (bookmarks)
  • Resume management (with WP Career Board Pro)

For admins:

  • Full admin control over jobs, applications, employers, and candidates
  • Moderation queue to approve jobs before they go live
  • Email notification system for all key events
  • GDPR-compliant data export and erasure tools

Key Differences From Other Job Board Plugins

Feature WP Career Board Traditional plugins
Page reloads on filter/apply No Yes
Built on WordPress Interactivity API Yes No
BuddyX Pro + Reign first-class support Yes No
No shortcodes required Yes Rarely
PHP 8.1 + WP 6.9 native Yes No

Requirements

  • WordPress: 6.9 or higher
  • PHP: 8.1 or higher
  • Browser: Any modern browser (Chrome, Firefox, Safari, Edge)

Free vs Pro

WP Career Board is free and fully functional as a standalone job board. WP Career Board Pro extends it with:

  • Resume builder with structured sections
  • Custom field builder for jobs, companies, and candidates
  • Application pipeline (ATS-style Kanban stage tracking)
  • Credit system with WooCommerce, PMPro, and MemberPress integration
  • Multi-board engine
  • Job alerts (saved searches sent by email)
  • AI job descriptions (auto-generate with AI)
  • Job map (interactive map with geocoded pins)
  • Job feed (RSS/XML for aggregators)
  • Priority support from the Wbcom Designs team

Start free. You can install WP Career Board and run a complete job board at no cost. Upgrade to Pro when you need advanced features.

Installation

WP Career Board is distributed exclusively via wbcomdesigns.com. It is not available on WordPress.org.

Before You Begin

Make sure your site meets these requirements:

  • WordPress 6.9 or higher
  • PHP 8.1 or higher
  • A modern block theme or classic theme (Reign or BuddyX Pro recommended)

Install the Plugin

  1. Log in to your WordPress admin (/wp-admin)
  2. Go to Plugins → Add New → Upload Plugin
  3. Click Choose File and select the wp-career-board.zip file you downloaded from wbcomdesigns.com
  4. Click Install Now
  5. Click Activate Plugin

Plugin Upload Screen

After activation, you will see the WP Career Board menu item in your admin sidebar.

What Gets Created on Activation

When you activate the plugin for the first time, WP Career Board automatically:

  • Creates three custom post types: Jobs, Companies, and Applications
  • Registers job taxonomies: Category, Job Type, Location, Experience Level, and Tag
  • Creates two user roles: Employer and Candidate
  • Adds the WP Career Board top-level menu to wp-admin
  • Launches the Setup Wizard to help you create your pages

After Activation

You will be redirected to the Setup Wizard. The wizard creates all required pages with the correct blocks in about 30 seconds. See Setup Wizard for the full walkthrough.

If you dismiss the wizard, you can run it again any time from WP Career Board → Settings → Run Setup Wizard (the button in the page header).

Updating the Plugin

  1. Download the latest version from your account at wbcomdesigns.com
  2. Go to Plugins → Add New → Upload Plugin
  3. Upload the new zip - WordPress will ask if you want to replace the current version
  4. Click Replace current with uploaded

Note: Your settings, jobs, applications, and user data are preserved on updates.

Setup Wizard

The Setup Wizard is the fastest way to get your job board up and running. It creates all the pages you need in two quick steps.

Setup Wizard - Welcome Screen

What the Wizard Does

Step 1 - Create Pages

The wizard creates five pages automatically, each with the correct block placed and configured:

Page Block(s) Purpose
Find Jobs Job Search + Job Filters + Job Listings Main job board browse page
Employer Registration Employer Registration Unified registration for both employers and candidates (users choose "Find a Job" or "Hire Talent")
Employer Dashboard Employer Dashboard Employer manages jobs + applications
Candidate Dashboard Candidate Dashboard Candidate tracks applications + saved jobs
Companies Company Archive Browsable company directory

Step 2 - Sample Data

Optionally install demo content - 3 companies, 8 published jobs across multiple categories, and all taxonomy terms. This lets you see how the board looks with real content before going live.

Safe to re-run. The wizard checks for existing pages first. If a page with the correct block already exists, it will not create a duplicate.

Extensible. WP Career Board Pro and other add-ons can append their own steps using the wcb_wizard_steps filter and their own pages using the wcb_wizard_required_pages filter.

Running the Wizard

  1. After plugin activation, the wizard launches automatically
  2. Click Create Pages & Continue - the wizard creates all pages and shows a progress indicator
  3. On Step 2, optionally click Install Sample Data to add demo content
  4. Click Finish Setup to complete

Setup Wizard - Pages Created

Running the Wizard Again

If you dismissed the wizard or need to reset your pages:

  1. Go to WP Career Board → Settings
  2. Click Run Setup Wizard in the header

After the Wizard

Once complete, your site has a working job board. Next steps:

Adding Blocks to Pages

WP Career Board uses WordPress blocks to display everything on the frontend. Each block handles a specific part of the job board experience.

Available Blocks

WP Career Board includes 15 blocks, all registered in the WP Career Board category in the block inserter.

Block What It Does
Candidate Dashboard Tabbed candidate dashboard: My Applications and Saved Jobs. My Resumes and Job Alerts tabs are added by Pro.
Company Archive Interactive company directory with grid/list toggle and industry/size filters.
Company Profile Public company profile with owner inline-edit and active job listings.
Employer Dashboard Tabbed employer dashboard with 6 tabs: Overview, My Jobs, Post a Job, Applications, Company Profile, and Settings.
Employer Registration Unified registration form for both employers and candidates. Users choose "Find a Job" (candidate) or "Hire Talent" (employer) on the same form.
Featured Jobs Static server-rendered grid of featured (flagged) jobs. Good for homepages.
Job Filters Taxonomy filter dropdowns (category, type, location, experience) for the job listings grid.
Job Form Multi-step (4-step) wizard for employers to post new jobs. Best for the full Post-a-Job experience.
Job Form (Single-Page) Every field on one screen - sidebar, modal, partner page, single-page-site alternative to the wizard. Submits to the same endpoint and honours the same field-builder filters. Posting only; editing routes through the wizard.
Job Listings Reactive job listings grid with load-more and bookmark toggle. Updates on search/filter without page reload.
Job Search Keyword search bar that drives the job listings grid.
Job Search Hero Full-width search form with optional category, location, and job type filter dropdowns. Horizontal or vertical layout. Good for homepages.
Job Single Full job detail view with a slide-in application panel.
Job Stats Horizontal stat strip showing total jobs, companies, and candidates.
Recent Jobs Static list of the most recently published jobs. Good for sidebars or homepages.

WP Career Board Pro adds 15 additional blocks: AI Chat Search, Application Kanban, Board Switcher, Credit Balance, Featured Candidates, Featured Companies, Job Alerts, Job Map, My Applications, Open to Work, Find Resumes, Resume Builder, Resume Map, Resume Search Hero, and Resume Single. See the Pro Blocks Reference for details.

Adding a Block to a Page

  1. Open any page in the WordPress editor (Gutenberg)
  2. Click the + button to add a block
  3. Search for "Career Board" or the block name
  4. Click the block to insert it

Block Inserter - Career Board Blocks

The Job Board Page (Recommended Layout)

For the main jobs page, use this block arrangement in order:

  1. Job Search - sits at the top, provides the search input
  2. Job Filters - sits below search, provides the filter dropdowns
  3. Job Listings - sits below filters, displays the results

All three blocks are connected - they automatically coordinate with each other on the same page. No configuration required.

Jobs Page Layout

Configuring Block Settings

Some blocks have settings you can adjust in the block sidebar:

Job Listings:

  • Jobs per page - how many jobs to show before the "Load more" button
  • Layout - grid (default) or list view

Job Search Hero:

  • Layout - horizontal (default) or vertical
  • Show Category Filter, Show Location Filter, Show Job Type Filter - toggle each filter dropdown on or off

Job Form (Single-Page):

  • Board - target a specific board (multi-board sites only). Single-board sites can leave this at 0 and the default board is used.
  • Show Company Field - show or hide the company name field (on by default; useful to hide for staff-only embeds where the company is implied)
  • Compact - tighter vertical rhythm for sidebars and modals

Featured Jobs:

  • Jobs per page - how many featured jobs to display (default: 3)
  • Title - optional heading above the grid
  • Show "View All" link - toggle the link to the full job board

Recent Jobs:

  • Count - how many recent jobs to list (default: 5)
  • Show "View All" link - toggle the link to the full job board

Company Archive:

  • Companies per page - how many companies per page (default: 20)
  • Layout - grid or list

Job Stats:

  • Toggle Show Jobs, Show Companies, Show Candidates independently to display only the counts you want.

To access these settings, click the block in the editor and look at the Block panel in the right sidebar.

The Setup Wizard vs Manual Setup

The Setup Wizard creates pages with the correct blocks already placed. You only need to add blocks manually if:

  • You want to embed the job board on an existing page
  • You want a custom layout or custom page template
  • You dismissed the wizard

Tip: If the Setup Wizard already created your pages, you don't need to add blocks manually. Check WP Career Board → Settings → Pages to see which pages are currently assigned.

Using Shortcodes (Classic Editor)

If you're using the Classic Editor or a page builder that doesn't support Gutenberg blocks, you can use shortcodes instead. Every major block has a shortcode equivalent:

Shortcode Block
[wcb_job_listings] Job Listings
[wcb_job_search] Job Search
[wcb_job_form] Job Form (4-step wizard)
[wcb_job_form_simple] Job Form (Single-Page)
[wcb_employer_dashboard] Employer Dashboard
[wcb_registration] Employer Registration
[wcb_candidate_dashboard] Candidate Dashboard
[wcb_company_archive] Company Archive
[wcb_job_stats] Job Stats
[wcb_recent_jobs] Recent Jobs

Simply paste the shortcode into any page or post content area. The shortcode renders the same output as its Gutenberg block counterpart.

Day-1 Quickstart Workflow

You've installed the plugin. Now what?

This is the shortest path from "fresh install" to "first job posted, first applicant reviewed." Five tasks, in order, plus where to go next when each is done.

1 - Finish the setup wizard

If you skipped the wizard during activation, run it now from Career Board → Setup. The wizard:

  • Creates the seven required pages (Find Jobs, Post a Job, Candidate Dashboard, Employer Dashboard, Find Companies, Find Candidates, Employer Registration).
  • Generates a starter Career Board with sample categories and types.
  • Walks you through optional sample-data installation so you can see real-looking content before you start typing your own.

Skip if: you've already completed it. Verify under Career Board → Settings → Pages that all seven pages are mapped.

2 - Add the menu items your site needs

Open Appearance → Menus and add at least:

  • For Jobs/find-jobs/
  • For Employers/post-a-job/ or /employer-dashboard/
  • For Candidates/candidate-dashboard/
  • Companies/find-companies/

A career-board site that doesn't surface these on the main navigation silently loses both candidates and employers - they can't find the pages even when they exist.

3 - Post your first job (yourself, as admin)

Treat this as a smoke test of the whole pipeline.

  1. Go to /post-a-job/ (or click "Post a Job" from your menu).
  2. Fill the form with a real-looking listing - title, company, description, salary range, location, category.
  3. Submit. If you have moderation enabled, the job lands in Career Board → Jobs → Pending. Approve it.
  4. Visit /find-jobs/ - your job appears in the listing.
  5. Click into it - the single job page should look the way you want candidates to see it. If something looks wrong (e.g. company info missing), it's worth fixing now before you invite real employers.

4 - Apply to it (yourself, as a test candidate)

  1. Log out, or open a private window.
  2. Register a test candidate account at /candidate-dashboard/ → Register tab.
  3. Apply to the job you just posted. Upload a real resume PDF and write a real cover letter - see what the experience feels like.
  4. Switch back to admin. Go to Career Board → Applications. Your test application should be there.
  5. Click into it. This is the screen your real employers will see when they review applicants. If you don't like how it looks, tweak the Application Details widget order (admin guide covers customization).

5 - Decide on moderation, credits, emails

Three settings that determine the day-2 experience:

  • Moderation (Career Board → Settings → General). Auto-publish jobs or require admin approval. Most marketplace sites use approval; most internal job boards auto-publish.
  • Credits (Pro only - Career Board → Settings → Credits). Turn on if you want to charge employers per posting. Most community boards leave this off and use a monthly Premium membership instead via PMPro / WooCommerce Subscriptions.
  • Email notifications (Career Board → Emails). Make sure candidate-application-received and employer-new-application emails are configured - they're how your candidates know they successfully applied and how your employers know to log in.

You're ready

Once steps 1-5 are done, the site is operationally ready. Real employers can register, post jobs, and review applicants. Real candidates can browse, apply, and track their applications.

What comes next depends on what you're building:

If you're running... Read next
A community / public job board for-employers/02-post-a-job.md - the full employer flow
A paid job board admin-guide/06-credit-system.md - credit setup
An internal team hiring board admin-guide/01-settings.md - auto-publish + role config
A site with existing classic-editor pages for-employers/11-page-builder-embeds.md - shortcodes

Troubleshooting Day-1 issues

  • Pages 404 after wizard - flush rewrite rules: Settings → Permalinks → Save (no changes, just save).
  • Apply button missing on jobs - the candidate must be logged in, or you must have Allow guest applications enabled.
  • No "Post a Job" link for employers - the employer needs the wcb_post_jobs capability. Site admin has it by default; for other users, grant it via the Users page or use a role manager.
  • Emails not arriving - your site's transactional email isn't set up. Install an SMTP plugin (FluentSMTP, WP Mail SMTP, etc.) and configure a real sending domain. Career Board's emails go through wp_mail like every other plugin.

Installing & Activating WP Career Board Pro

Pro feature - Requires a WP Career Board Pro license from wbcomdesigns.com.

WP Career Board Pro is an add-on plugin. It requires the free WP Career Board plugin to be installed and active first.

Step 1: Install the Pro Plugin

  1. Log in to your account at wbcomdesigns.com
  2. Go to My Account → Downloads
  3. Download wp-career-board-pro.zip
  4. In your WordPress admin, go to Plugins → Add New → Upload Plugin
  5. Select the downloaded zip and click Install Now
  6. Click Activate Plugin

If the free plugin is not active, activation will be blocked with an error message. Install and activate WP Career Board (free) first, then retry.

Step 2: Activate Your License

  1. Go to WP Career Board → Settings → License
  2. Paste your license key in the License Key field
  3. Click Activate License

A confirmation shows your license status, expiry date, and how many sites are using this license.

License Statuses

Status Meaning
Active Valid license, updates available
Expired License period ended - plugin still works but no updates
Inactive Key entered but not yet activated on this site
Invalid Key does not match any license
No activations left All license slots used - deactivate from another site first

License Tiers

Tier Sites
Single Site 1 site
Business 5 sites
Agency Unlimited sites

Deactivating

To move your license to a different site:

  1. Go to WP Career Board → Settings → License
  2. Click Deactivate License
  3. Activate on the new site

You can also manage all site activations from your account at wbcomdesigns.com.

Renewing

The plugin continues to work after expiry - you just stop receiving updates. To renew, log in to wbcomdesigns.com → My Account → Licenses → Renew.

What Activates with Pro

On activation, WP Career Board Pro:

  • Creates additional Pro database tables
  • Adds Pro settings tabs to WP Career Board → Settings
  • Registers 15 additional blocks in the block inserter
  • Enables the Resume Builder, Field Builder, Pipeline, Credit System, Multi-Board, Job Alerts, Job Map, and AI Search modules

Pro Setup Wizard

After activating the Pro plugin, a Pro Setup Wizard runs automatically to configure Pro-specific settings (pipeline stages, credits, resume page, etc.). This wizard appends its own steps to the standard wizard using the wcb_wizard_steps filter.

If the Free wizard already ran, the Pro wizard renders as a focused mini-wizard that handles only the Pro steps. You can re-run it any time from WP Career Board → Settings → Run Setup Wizard.

What's New in 1.2.0

Released May 2026. WP Career Board 1.2.0 is the first public release since 1.0.x. It rolls up everything the 1.1.0 dev cycle produced (single-page job form, bulk applicant CSV export, salary range slider, deadline reminders, guest resume uploads, page-builder shortcode compatibility, rebuilt admin Edit Application screen, BuddyPress group-scoped boards, tiered credit pricing, and more) plus the QA roll-up that closed every Basecamp bug card from the 1.1.x cycle.

Free and Pro ship in lockstep at 1.2.0. Install both updates together.

What customers see right away

A centered setup wizard

The first-run wizard now sits centered on wide screens instead of left-aligned. Same content, less cognitive friction.

Setup wizard centered

A working Find Jobs filter row

Apply any filter on the Find Jobs page and the active-filter chip row now has comfortable spacing above the job cards. The filter-panel toggle chevron now renders through the unified Lucide icon system, so it matches every other icon on the site.

Find Jobs with active filter chip

Companies archive that aligns properly

The Companies grid now keeps meta chips at the same vertical position across every card, regardless of how long each tagline is. Footer ("View Profile") pins to the bottom of every card so the grid reads as a clean row.

Companies archive grid

My Applications as a proper table

The [wcbp_my_applications] shortcode and matching block now render as a semantic table with Job / Status / Submitted column headers. Candidate view shows just the candidate's own applications; employer view (when used with the employerId attribute) prepends an Applicant column.

My Applications candidate view

On narrow viewports the table collapses to a card layout with each row's data labeled in-place, so phones see the same data structure without a horizontal scrollbar.

What Pro customers see

Open to Work widget with real candidate info

The Open to Work sidebar widget now reads the resume form's uploaded photo (not the BuddyPress / Gravatar avatar), shows the candidate's location, displays years of experience, and lists their top three skills. When the resume form has not been completed yet, the widget falls back to an initial-letter chip in the brand color.

Open to Work block

Featured Candidates with reliable skill display

The Featured Candidates block now falls back to skill data stored in resume meta when the taxonomy is empty, so candidates whose skills-sync hook did not fire still display correctly.

Featured Candidates block

Credits admin notice when setup is incomplete

A new yellow banner appears on Settings → Credits when a Purchase URL is set but no product is mapped to a positive credit amount. Without a mapping, an employer who completes the order would receive zero credits. The Buy Credits button on the credit-balance block stays hidden until the mapping is added.

Credits admin warning

What admins see in workflows

Test Email button now works regardless of template status

Previously, clicking Send test on an email template that was toggled off in settings would silently fail (the early-return in send() skipped both wp_mail() and the log row). The endpoint reported sent: false and the JS button painted "Failed".

1.2.0 adds a public AbstractEmail::test_send() bridge that bypasses the enabled gate, dispatches the email, and writes a sent_test status row to the notifications log so admin previews stay separate from production delivery metrics in the activity log.

Test Email Sent state

Direct metaFilter on the Job Listings block

The Job Listings block has a metaFilter attribute (and the matching ?meta_<key>=<value> REST query param) that filters jobs by post-meta. Pre-1.2.0 this required registering each meta key through the wcb_jobs_allowed_meta_filters PHP filter first.

1.2.0 auto-allows any _wcb_* namespaced meta key. The plugin owns that prefix, so there is no probe risk; customers can drop the block in the editor and use any of our job meta as a filter without writing PHP. Custom or non-WCB meta still requires the existing opt-in filter.

metaFilter block attribute

Pair release

Pro 1.2.0 ships in lockstep. Both plugins must be at the same version at runtime. See Pro's What's New for the Pro-side feature list (single-page resume form, BuddyPress group-scoped boards, tiered credit pricing, BP activity stream integration, member directory filters, group-scoped moderation, the rebuilt admin Boards tab with pagination + search, and more).

Upgrade notes

  • Lockstep: install Free 1.2.0 and Pro 1.2.0 together. The Pro dependency check refuses to load against an older Free.
  • Versions: the WCB_VERSION and WCBP_VERSION constants both move to 1.2.0. Stable tag in readme.txt matches.
  • Translations: the .pot files have been regenerated and now cover every string in the codebase as of 1.2.0 (1172 Free strings, 696 Pro strings).
  • No data migration required.

For Employers

How employers post jobs, review applications, and manage hiring.

Employer Overview

Employers are businesses or individuals who post jobs and manage applications on your job board. This section covers everything an employer can do.

Employer Dashboard Overview

What Employers Can Do

  • Register an account with the Employer role
  • Post new jobs using a guided multi-step form
  • Manage all their job listings (edit, close, re-open, publish)
  • Review and filter incoming applications
  • Set up and edit a public company profile
  • Receive email notifications for new applications

The Employer Role

When a user registers as an employer, they get the Employer role. This gives them access to the Employer Dashboard, which contains six tabs:

  1. Overview - summary stats and quick actions
  2. My Jobs - manage all job listings
  3. Post a Job - submit a new job using the multi-step form
  4. Applications - review and filter incoming applications
  5. Company Profile - set up the public employer page
  6. Settings - notification and account preferences

Admins can also manually assign the Employer role to any user from Users → Edit User in wp-admin.

How Applications Reach Employers

When a candidate applies to a job, the employer sees the application immediately in their dashboard. They get:

  • Applicant name and email
  • Application status (Submitted / Reviewing / Shortlisted / Rejected / Hired)
  • Submission date
  • A direct link to the applicant's profile (if they are a registered candidate)

Section Contents

Post a Job

Jobs are posted from within the Employer Dashboard - there is no separate "Post a Job" page. Navigate to your dashboard and click the Post a Job tab in the top navigation, or use the + Post a Job button on the Overview tab.

Job Form - Step 1

Before You Post

Make sure you are logged in as a user with the Employer role. If you are not logged in, the dashboard will show a prompt to register or log in.

Step-by-Step: Posting a Job

The job form is a 4-step wizard that walks you through each section of the listing.

Step 1 - Basics

Enter the core information about the role:

  • Job Title - the position name (required)
  • Job Description - full description of the role, responsibilities, and requirements

Step 2 - Details

Provide the specifics:

  • Location - city, state/country, or Remote
  • Salary - optional; enter a range or a fixed amount
  • Job Type - Full-time, Part-time, Contract, Freelance, or Internship
  • Experience Level - Entry, Mid, Senior, Lead, or Executive
  • Application Deadline - optional; date after which the job closes automatically

Step 3 - Categories

Classify the job so candidates can find it:

  • Job Category - select the industry or function category
  • Tags - add relevant tags for better discoverability

Step 4 - Preview

Review all the information you entered across the previous steps. If everything looks correct, click Submit Job to post.

Job Form - Review Step

After Submitting

If moderation is ON (default): your job is submitted for admin review. You will see a "Pending review" message. The job goes live after the admin approves it.

If moderation is OFF: your job is published immediately and appears on the job board.

You will receive a confirmation email when your job goes live.

Editing a Submitted Job

You can edit a pending or published job from your Employer Dashboard → My Jobs → Edit. Changes to a published job may require re-approval depending on your admin's settings.

Job Expiry

If your admin has set an expiry period (e.g., 30 days), your job will automatically close on that date. You will receive an email notification before it expires, and you can re-open it from your dashboard.

Single-Page Form - when the 4-step wizard is overkill

The default post-a-job experience is a 4-step wizard. For some embed points the wizard is too tall: sidebars, modal overlays, partner pages, single-page sites, and classic themes with limited vertical real estate. WP Career Board ships a second block, Job Form (Single-Page), that puts every field on one screen.

It submits to the same /wcb/v1/jobs endpoint, honours the same wcb_job_form_fields filter for custom fields, and respects the same employer-role gate. The only thing it does not support is edit mode - editing a job always routes through the wizard from the Employer Dashboard.

Block settings

  • Board - target a specific board (multi-board sites only)
  • Show Company Field - toggle the company name field on or off (on by default)
  • Compact - tighter vertical rhythm for narrow embed contexts

Adding the single-page form

In Gutenberg, search for Job Form (Single-Page) in the block inserter. In classic editors or page builders, use the shortcode:

[wcb_job_form_simple]
[wcb_job_form_simple boardId="42" showCompanyField="false" compact="true"]

When to use which: keep the wizard on your primary "Post a Job" page - the dashboard already places it for you. Reach for the single-page form when you need a job form alongside other content - homepage hero, partner page, sidebar widget, or modal overlay.

Manage Your Jobs

The My Jobs tab in the Employer Dashboard shows all the jobs you have posted, with quick actions to manage each one.

Employer Dashboard - My Jobs Tab

Accessing Your Jobs

  1. Go to the Employer Dashboard page (created by the Setup Wizard)
  2. The My Jobs tab is active by default
  3. You will see a list of all your jobs with their current status

Job Statuses

Status Meaning
Published Live on the job board, visible to candidates
Draft Saved but not yet submitted for review
Pending Submitted, waiting for admin approval
Closed No longer accepting applications; hidden from the board
Expired Passed the expiry date; same as Closed

Actions per Job

Each job card shows these quick-action buttons:

  • View ↗ - opens the public job listing in a new tab
  • Edit - opens the job for editing in the job form
  • Close - closes the job and stops accepting applications (published jobs only)
  • Reopen - puts a closed job back on the board (closed jobs only)
  • Publish - submits a saved draft for approval (draft jobs only)

Job Card Actions

Editing a Job

  1. Click Edit on any job
  2. The multi-step Job Form opens pre-filled with the current data
  3. Make your changes and click Update Job

Note: If moderation is enabled, edits to a published job may require re-approval. The job stays live while under review.

Closing a Job

Click Close to stop accepting new applications. The job is removed from the job board listing but the data is preserved. You can reopen it later.

Use this when:

  • You have filled the position
  • You want to temporarily pause applications

Application Count

Each job card shows the number of applications received. Click the count to jump directly to the Applications view for that job.

Review Applications

The Applications view in the Employer Dashboard shows every application received across all your jobs. You can filter by job and update the status of each applicant.

Employer Dashboard - Applications View

Accessing Applications

  1. Open the Employer Dashboard
  2. Click the Applications tab in the top navigation

You will see a list of all applicants across your jobs.

What You See per Applicant

Each application card shows:

  • Applicant name and initials avatar
  • Email address
  • Which job they applied to
  • Application date
  • Current status - see statuses below

Filtering by Job

If you have multiple jobs, use the Filter by job dropdown at the top to see only the applications for a specific listing.

Application Statuses

Status When to use
Submitted Application received - not yet reviewed
Reviewing You are actively reviewing this candidate
Shortlisted Candidate is worth moving forward
Rejected No longer considering this applicant
Hired Offer accepted - position filled

Updating Application Status

Click the status dropdown on any application card to change it. Status changes are saved immediately - no page reload required.

With WP Career Board Pro: the status system is replaced by a fully customizable stage pipeline (Screening → Interview → Offer → Hired/Rejected) with a Kanban board view. See Application Pipeline.

Contacting Applicants

Click the applicant's email address to open a new email in your mail client. All communication happens outside the plugin - WP Career Board does not have a built-in messaging system in the free version.

When Candidates Withdraw

If a candidate withdraws their application, it is permanently deleted and will no longer appear in your application list.

Company Profile

Every employer gets a public Company Profile page that candidates can browse. It shows your company information and all your active job listings in one place.

Company Profile - Public Page

What the Company Profile Shows

  • Company name and logo
  • Industry and company size
  • Website link
  • "About the Company" description
  • All currently active job listings from this company

Candidates can click through to any individual job listing directly from your company page.

Setting Up Your Profile

You can edit your company profile from two places:

From the Employer Dashboard:

  1. Open the Employer Dashboard
  2. Click the Company Profile tab
  3. Fill in your company details
  4. Click Save

Inline on the public profile page:

  1. Visit your company's public profile page while logged in
  2. Click the Edit icon next to any field
  3. Edit inline and save

Company Profile - Inline Edit

Profile Fields

Field Required Notes
Company Name Yes Displayed as the page title
Logo No Recommended size: 200×200px
Industry No Shown as a tag on company cards
Company Size No e.g., 1-10, 11-50, 51-200
Website No Shown as a clickable link
About the Company No Multi-paragraph description

Company Profile URL

Your company profile URL is automatically generated from your company name: yourdomain.com/company/your-company-name/

Who Sees the Company Profile

The Company Profile page is public - any visitor can see it, even without an account. The Company Archive page (if enabled) lets visitors browse all companies on your board.

Tip: A complete company profile with a logo and description significantly increases candidate trust and application rates.

Application Pipeline

Pro feature - Requires WP Career Board Pro.

The Application Pipeline replaces the free version's status system (Submitted / Reviewing / Shortlisted / Rejected / Hired) with a fully customizable ATS-style stage workflow and a visual Kanban board.

Application Pipeline - Kanban Board

Free vs Pro

Free Pro
Application statuses Submitted, Reviewing, Shortlisted, Rejected, Hired Any custom stages you define
Pipeline view List only Kanban board + list
Terminal outcomes Rejected / Hired Hired / Rejected (configurable, per-board)
Stage history No Yes

Default Stages

When you first enable the Pipeline, these stages are created automatically:

  1. Submitted (starting stage)
  2. Screening
  3. Interview
  4. Offer
  5. Hired (terminal - outcome: Hired)
  6. Rejected (terminal - outcome: Rejected)

You can rename, add, reorder, or delete any of these.

Configuring Your Stages

Go to WP Career Board → Boards, then open the board you want to configure and click the Stages tab.

Adding a Stage

  1. Click + Add Stage
  2. Enter the stage name (e.g., "Technical Test")
  3. Choose a color for the stage badge
  4. Toggle Terminal stage on if this is a final outcome
  5. If terminal, select the outcome: Hired or Rejected
  6. Click Save

Stage Colors

Choose colors that give instant visual meaning:

  • Green tones → positive stages (Offer, Hired)
  • Red tones → rejections
  • Blue/gray tones → neutral stages (Screening, Interview)

Terminal Stages

When you move a candidate to a terminal stage:

  • Their application status is automatically set to Closed
  • If outcome is Hired - the job's hired counter increments
  • If outcome is Rejected - the candidate receives a rejection email (if enabled)

You must have at least one Hired terminal stage and one Rejected terminal stage.

Reordering and Deleting

  • Reorder: Drag and drop stage rows - order determines Kanban column order (left to right)
  • Delete: If applications are in that stage, you'll be asked to move them to another stage first

Using the Kanban Board

  1. Open Employer Dashboard → Applications
  2. Click Kanban View in the top right

Each column is a stage. Drag applicant cards between columns to move candidates through your pipeline. Click any card to open the full application details.

Bulk Moving

In list view, select multiple candidates with checkboxes, then use the Move to Stage dropdown to move all at once.

Per-Board Stages

If you use the Multi-Board Engine, each board has its own stage configuration. Go to WP Career Board → Boards, select the board, and configure its stages independently.

Find Resumes

Pro feature - Requires WP Career Board Pro.

The Find Resumes block displays a public-facing archive of candidate resumes. Employers and admins can browse candidate profiles filtered by skills, location, and job title - without waiting for candidates to apply.

How It Works

Candidates build their resumes using the Resume Builder. When a candidate sets a resume to Public, it appears in the Find Resumes archive. Resumes set to Private are never shown here.

Employers can browse the archive, filter by skills and location, and click through to a full resume page.

Adding Find Resumes to a Page

  1. Create a new page (e.g., "Find Candidates" or "Resume Database")
  2. In the WordPress editor, add the Find Resumes block
  3. Publish the page

No settings configuration is required - the block renders all public resumes automatically.

Filtering

Visitors can filter resumes by:

  • Skills - matches against the Skills section of each resume
  • Location - matches against the candidate's listed location
  • Job Title - keyword match against the candidate's most recent job title

Filters update the list without a page reload.

Candidate Privacy

Candidates control their resume visibility:

  • Private (default) - visible only to employers who receive an application from that candidate
  • Public - visible in the Find Resumes archive

Candidates can change visibility at any time from the Resume Builder or their dashboard.

Linking to Resume Single Page

When a visitor clicks a resume in the archive, they are taken to the Resume Single page - a full formatted view of that candidate's resume. The Resume Single block handles this display.

To enable this:

  1. Create a page with the Resume Single block
  2. Assign it in WP Career Board → Settings → Pages → Resume Page

Quick Job Form (single-page)

The Quick Job Form is a one-screen alternative to the multi-step job-form wizard. Drop it into any sidebar, modal, partner page, or page builder. Captures the core fields an employer needs to publish in one submit - no tab switching, no wizard navigation.

Sibling of the full Post a Job form (the 4-step wizard) - both share the same custom-field hook and persistence layer, so anything you add via wcb_job_form_fields appears on both surfaces.

When to use it

  • Embed in a sidebar widget so partners can post a job from any page on your site without navigating to the dashboard.
  • Drop into a modal triggered from a "Post a job" CTA on a marketing page.
  • Embed on a partner / co-marketing site - the Block + shortcode both forward the REST namespace, so cross-site posts work as long as the partner has a logged-in employer session.
  • Onboarding flows where you want to capture the first job inline during account creation, not after.

How to add it

As a block

In the WordPress editor, add the Job Form (Single-Page) block. Available attributes:

Attribute Type Default What it does
redirectUrl URL '' Where to send the employer after a successful post (defaults to the new job's permalink)
boardId int 0 Lock the form to a specific board (useful for multi-board sites)
categoryDefault string slug '' Pre-select a job category

As a shortcode

For page builders or classic editor:

[wcb_job_form_simple]
[wcb_job_form_simple boardId="42"]
[wcb_job_form_simple redirectUrl="/thanks/"]

Every Block attribute forwards to the shortcode using the same name. Page builders (Elementor, Divi, Bricks, Beaver Builder, classic editor) all support attribute passthrough.

As an Elementor / Divi / Bricks / Beaver Builder embed

Use the shortcode widget in your page-builder of choice. See the Page-builder embeds guide for the full attribute reference shared by every shortcode.

Fields captured

Field Required Note
Job Title Yes
Job Description Yes Block editor / rich text
Location No Free text or taxonomy term
Job Type No Full-time / Part-time / Contract / Freelance / Internship
Salary range No min + max, currency, period (yearly / monthly / hourly)
Application deadline No Date picker
Custom fields Optional Whatever your wcb_job_form_fields filter contributes

Fields specific to your industry can be added via the Custom fields filter - they'll appear on this form AND the multi-step form automatically.

What happens on submit

The form posts to the same REST endpoint as the multi-step form (POST /wcb/v1/jobs), so:

  • Moderation rules apply identically (jobs land in pending if moderation is enabled).
  • Featured-status, board assignments, and credit deduction flow through the standard pipeline.
  • BuddyPress activity-stream entries fire on approval (Pro).
  • Email notifications fire to whoever the site config dictates (admin moderator / employer-confirmation / etc.).

Limitations

  • Single-screen UX means there's no preview step before publish. Employers can still edit immediately afterward via the dashboard.
  • Multi-image uploads (company logos, banner art) are not part of this form - those still happen via the company profile editor.

Bulk Applicant CSV Export

Export selected applications from the admin list table to a UTF-8 CSV spreadsheet - one row per applicant, ready to drop into Google Sheets, Excel, or your ATS.

Where to find it

In wp-admin, navigate to Career Board → Applications. The list table now ships a Bulk actions dropdown with an Export selected to CSV option.

How to use it

  1. Filter / search the list down to the applications you want (status filters, job filters, date ranges all work).
  2. Tick the row checkboxes (or the column-header checkbox to select the whole filtered set).
  3. Open the Bulk actions dropdown, choose Export selected to CSV, click Apply.
  4. The browser downloads wcb-applications-YYYY-MM-DD.csv.

Columns in the export

Column Source
applicant_name Application post title
applicant_email Application meta (or candidate user email)
job_title Linked wcb_job post title
job_id Numeric ID for joining back to the jobs table
status Application status slug (submitted, reviewing, shortlisted, rejected, wcb_closed, wcb_expired)
applied_at ISO 8601 timestamp
cover_letter Plain-text version of the cover letter (multi-line preserved with \n)
resume_url Direct link to the uploaded resume file

If you've added custom application fields via the wcb_application_form_fields_groups filter, those fields automatically appear as additional columns.

Encoding

UTF-8 with a BOM so Excel renders non-ASCII names correctly without manual import-wizard configuration. Multi-line cover letters preserve newlines using standard CSV quoted-string semantics.

Permissions

Only users with the wcb_manage_applications ability can export. Site admins always have it; employers can be granted via the Abilities API.

Your Credit Balance (Employer View)

If your site uses the Credit System, this is what you, the employer, see and how the flow works from your side. The admin-side setup is covered in admin-guide/06-credit-system.md.

This doc only applies when: your site admin has enabled the Credit System and you, as an employer, are required to spend credits to post jobs.

Where to See Your Balance

Career Board → Employer Dashboard. The Credits panel in the sidebar shows:

  • Your current balance.
  • A "Buy Credits" button (only appears when the admin has set up a purchase page).
  • A "View transaction history" link to see every top-up and deduction.

The balance also appears as a banner on the Post a Job page when you're about to submit - so you don't have to leave the form to check.

How Credits Are Spent

The cost depends on which Board you're posting to. Different boards can have different per-post prices (admin sets this up).

The sequence:

  1. You start filling the Post a Job form.
  2. The banner at the top reads, e.g., "Posting deducts 1 credit. Balance after: 99 (currently 100)."
  3. You submit the job.
  4. Credits are held - reserved but not yet consumed.
  5. If your site requires admin approval, the credits stay held until the admin acts.
  6. If approved - credits are deducted permanently.
  7. If rejected - held credits are released back to your balance.
  8. If you withdraw the job before approval, held credits are released.

Insufficient Credits

If your balance is below the cost when you try to submit:

  • The submit button is disabled.
  • The banner shows: "This board requires N credits. Your balance: M. Please purchase more credits."
  • A "Buy Credits" link appears (when the admin has configured a purchase page).

You can save the form as a Draft in this state - your job won't post, but the form contents are preserved so you don't have to re-type when you top up.

Buying Credits

What you see when you click Buy Credits depends on how your admin set up the purchase flow:

If your admin set up... You'll see...
WooCommerce store A standard WooCommerce product page or cart
Paid Memberships Pro A PMPro membership level checkout
MemberPress A MemberPress signup page
Custom URL Whatever page the admin pointed it at

Complete the checkout the same way you would buy any product. Once the order completes, credits are added to your balance automatically and you can immediately go back to posting your job.

If the order goes into Pending (e.g. bank transfer payments), credits are NOT added until the order moves to Completed - check with your admin if you've paid but credits haven't appeared after a few minutes.

Featured Job Upgrades

If the admin has enabled featured upgrades, you can pay extra credits to promote your job to the top of search results for a configurable duration. The "Featured" toggle appears on the Post a Job form with the credit cost shown next to it.

Once a featured job's window expires, the listing stays - it just loses the boost. You can renew the upgrade from your Employer Dashboard → Jobs → Featured tab.

Transaction History

Your Employer Dashboard → Credits → History shows every:

Type What it means
Top-up You bought credits (or admin granted them)
Hold Credits reserved for a pending job
Deduct Credits consumed for an approved job
Refund Credits returned (job rejected or you withdrew)

The history is your audit trail. If you ever dispute a charge, this is what to screenshot.

Refunds

If you posted a job that turned out to be wrong or got rejected, held credits return automatically. For an already-deducted job that the admin agrees should be refunded, contact your site admin - they can issue a manual refund from their Career Board → Reports panel. Auto-refund of deducted credits is not available because the job has been live and received exposure.

Frequently Asked

Do credits expire?

By default no - your balance never expires. Some sites configure this differently (e.g., monthly membership credits that reset each cycle). Check with your admin if you're on a recurring plan.

Can I gift credits to a colleague at the same company?

Not directly. Credits are per-account. If your colleague is an employer at the same company, they need their own account and their own credits. Contact the admin if you want to share a pool - they can grant credits manually to either account.

I bought credits but they're not showing.

Wait 1-2 minutes (the dashboard caches balance briefly), then log out and back in. If still missing, send your admin the order number - they can verify the payment landed and grant the credits manually if the automatic flow didn't fire.

Related

Page-builder Embeds (Elementor, Divi, Bricks, Beaver Builder)

Every WP Career Board block has a matching shortcode, and every shortcode now accepts the same attributes the block does. So if you build pages with Elementor, Divi, Bricks, Beaver Builder, or the classic editor, you can scope blocks the same way you would in the block editor.

Shortcode reference

Every WP Career Board block has a shortcode wrapper that accepts the same attributes. Use these in Elementor, Divi, Bricks, Beaver Builder, the classic editor, or anywhere a shortcode is accepted.

Block Shortcode
Job Listings [wcb_job_listings]
Job Search Hero [wcb_job_search_hero]
Job Form (multi-step) [wcb_job_form]
Job Form (single-page) [wcb_job_form_simple]
Job Search [wcb_job_search]
Job Single [wcb_job_single]
Job Filters [wcb_job_filters]
Featured Jobs [wcb_featured_jobs]
Recent Jobs [wcb_recent_jobs]
Job Stats [wcb_job_stats]
Company Archive [wcb_company_archive]
Company Profile [wcb_company_profile]
Candidate Dashboard [wcb_candidate_dashboard]
Employer Dashboard [wcb_employer_dashboard]
Employer Registration [wcb_employer_registration]
Modular Widgets [wcb_widget id="..."]

Back-compat alias: [wcb_registration] still works as a synonym for [wcb_employer_registration] - sites that already embedded the short form keep rendering. New pages should use the canonical tag.

Attribute passthrough

All shortcode attributes match the block attribute name (camelCase becomes lowercase-with-no-separator in some cases). For example:

[wcb_job_listings perPage="6" boardId="42" layout="list"]

Renders the same thing as the Job Listings block with perPage=6, boardId=42, layout=list.

Common scoping patterns

Show a board-scoped listing

[wcb_job_listings boardId="42" perPage="10"]

Only jobs assigned to board 42. Used on board-specific landing pages or partner pages.

Filter by custom meta

If you've registered a custom meta key via the wcb_jobs_allowed_meta_filters filter, you can scope a listing by that meta:

[wcb_job_listings metaFilter="industry:fintech" perPage="6"]

Embed a form on a marketing page

[wcb_job_form_simple redirectUrl="/thanks/"]

After successful submission, the employer is redirected to /thanks/ instead of the new job's permalink.

Render a single widget from the application screen

The new modular widget system on the Application Editor exposes its widgets as shortcodes too, so you can embed e.g. an applicant card on a partner profile page:

[wcb_widget id="applicant_card" application_id="987"]

Tips for page-builder users

  • Elementor - use the Shortcode widget, not "HTML". The HTML widget escapes shortcodes.
  • Divi - drop a Code module and paste the shortcode. The Visual Builder renders the live block.
  • Bricks - use the Shortcode element under Basic.
  • Beaver Builder - use the HTML module; Beaver Builder runs shortcodes through do_shortcode() automatically.
  • Classic editor - paste the shortcode anywhere. Works in posts, pages, custom post types, widgets.

All blocks render identically across these surfaces - same CSS, same Interactivity API behavior, same REST data flow.

Troubleshooting (Employers)

Common things employers hit, in plain language. If you're a site owner / admin, see admin-guide/07-troubleshooting.md for the admin-side debug path.

"I posted a job but it isn't showing up"

Three things to check, in order:

  1. Is it pending approval? Go to your Employer Dashboard → My Jobs. If the job is there with status "Pending" or "Under Review", the site is configured to require admin approval. Contact the site admin or wait for approval.
  2. Is it past the deadline? If you set an "Apply by" date in the past (or your draft sat too long and the date came and went), the job auto-expires. Open it from your dashboard and either extend the deadline or republish.
  3. Did the submit actually complete? Your dashboard shows every job you've created. If it's not there, the form didn't save - usually because of a network blip. Re-submit.

"Applicants aren't coming in"

Posting alone doesn't bring traffic. Check:

  • The job is on /find-jobs/ - visit it from a private window. If you can't find it there, candidates can't either.
  • Your job's URL has been shared. Share on LinkedIn, your company's social channels, internal Slack. New job boards build traffic over months.
  • The "Apply by" date isn't past. Expired jobs disappear from the default listing.
  • Your category, location, and type are typical search terms. A "Senior Frontend Engineer" gets more eyeballs than a job filed as "Other → Other".

"I keep getting 'Insufficient credits' when I try to post"

The site charges credits per posting. Your balance is on the Employer Dashboard → Credits panel.

  • You need to buy more. Click "Buy Credits" and complete the checkout. Once the order completes, your balance updates and you can post.
  • You bought credits but they didn't add. Wait 1-2 minutes (the dashboard caches the balance briefly). If still missing, contact the site admin with your order/receipt number.
  • Different boards cost different amounts. Switch to a cheaper board in the post-a-job form if it suits your role.

"My company profile changes aren't saving"

  • Make sure you're logged in as the company owner. Only the user attached to the company can edit it. Site admins can also edit any company.
  • Required fields. Some fields (company name, contact email) are required. If left blank, the save silently fails. Look for red asterisks on the form.
  • Special characters. If you pasted text with emoji or unusual characters and the save fails, copy the text into a plain editor first and re-paste.

"I'm not getting email notifications about new applications"

  • Check your spam folder. Most "missing email" complaints are spam-filter issues.
  • The site's email might not be configured properly. Contact the site admin and ask them to verify SMTP / email sending is working.
  • The notification might be disabled in your account. Go to Employer Dashboard → Settings → Notifications (if available) and confirm "New application" is turned on.

"The 'Apply on Company Site' button is missing from my job"

You set an external Apply URL but it isn't showing? Two things:

  • The URL must start with http:// or https://. Just typing company.com/careers won't work - the plugin filters out URLs without a scheme.
  • It only appears on the public job page. When you preview from your dashboard, the form's preview pane might not show it
    • check the live job URL instead.

"Candidates report the apply form is broken"

  • They might not be logged in. If your site requires login to apply, the Apply button shows but the form short-circuits. Tell candidates to register or log in first.
  • The site might have anti-spam (Turnstile/reCAPTCHA) enabled. Adblockers or strict browser settings can block the captcha script. If a candidate reports this, ask them to try in a different browser.
  • The resume file is too large. Default limit is 5 MB. Larger files get rejected at upload. Ask the candidate to resize/ re-export their PDF.

"I can't see the Pro features I'm paying for"

  • Pro plugin needs to be installed AND active. Site admin needs to do this - you can't enable it from your dashboard.
  • License needs to be activated. Site admin enters the license key under Career Board → Settings → License.
  • Some features depend on configuration. Job Map needs Google Maps API key, AI needs an OpenAI/Anthropic key, alerts need cron working. Site admin handles all this.

I'm stuck - what should I send my site admin?

Send them:

  1. The URL of the page where the problem happens.
  2. A screenshot of what you see vs. what you expect.
  3. The time and date the problem occurred (helps them check logs).
  4. Your user account email (so they can find your record).
  5. If applicable: your order/transaction number, the job title, the candidate's email.

Don't send screenshots of payment info or sensitive HR data - just the descriptive details.

Related

For Candidates

How candidates find jobs, apply, and manage their profile.

Candidate Overview

Candidates are job seekers who browse listings and apply on your job board. They get a personal dashboard to manage all their activity in one place.

Candidate Dashboard Overview

What Candidates Can Do

  • Browse and search job listings
  • Filter jobs by category, type, location, and experience level
  • Bookmark jobs to review and apply later
  • Apply for jobs with a cover letter and resume upload (PDF/DOC)
  • Track all applications and their statuses from a single dashboard
  • Receive email notifications when their application status changes
  • Set up job alerts to get notified when matching jobs are posted (Pro)

Registration

Visit the Employer Registration page (which despite its name handles both roles) and choose "Find a Job" to register as a candidate. The heading on the registration block is "Join WP Career Board". You'll need:

  • First name and last name
  • Email address
  • Password (minimum 8 characters)

After registration, you're automatically logged in and redirected to your Candidate Dashboard.

Employers choose "Hire Talent" on the same page - one unified registration form for both roles.

The Candidate Role

When a user registers as a candidate, they get the Candidate role. This gives access to:

  • The Candidate Dashboard - applications, saved jobs, resumes, job alerts
  • The ability to apply for jobs
  • The saved jobs (bookmarks) list
  • Job Alerts management (Pro)

Admins can manually assign the Candidate role from Users → Edit User in wp-admin.

Guest Applications

Candidates can apply without creating an account. Guest applicants provide their name and email during the application. They receive email updates but do not have a dashboard.

Tip for your users: Creating an account gives candidates the ability to track all applications, save jobs, and build a profile. Encourage registration.

Section Contents

Finding Jobs

The job board gives candidates a fast, reactive way to browse and narrow down listings - no page reloads, no waiting.

Job Listings Page

Browsing the Job Board

Visit the Jobs page on your site. You will see a grid of all currently active job listings, each showing:

  • Job title
  • Company name and logo
  • Location
  • Job type (Full-time, Part-time, etc.)
  • Posted date
  • Salary (if provided by the employer)

Click any card to open the full job detail page.

Searching by Keyword

Use the Search bar at the top of the job board to find jobs by keyword. The search looks through job titles and descriptions. Results update as you type.

Job Search Bar

Filtering Jobs

Use the Filter dropdowns to narrow results by:

Filter Options
Category Industry or function (e.g., Engineering, Marketing, Design)
Job Type Full-time, Part-time, Contract, Freelance, Internship
Location Country, state, or city
Experience Level Entry, Mid, Senior, Lead, Executive

You can combine multiple filters. Results update instantly after each selection.

To remove all filters at once, click Clear all in the filter bar.

Loading More Jobs

The job board loads a set number of jobs at a time (set by your admin). When you reach the bottom, click Load more to see additional listings.

Viewing a Job

Click any job card to open the full detail page. You will see:

  • Full job description
  • Company information with a link to the company profile
  • Application deadline (if set)
  • Salary range
  • Job type, location, and experience level
  • An Apply Now button to start the application

Job Single Page

Saving a Job for Later

Click the bookmark icon on any job card or job detail page to save it. Saved jobs appear in your Candidate Dashboard → Saved Jobs tab.

You can remove a saved job at any time from the dashboard.

Applying for Jobs

Applying is quick - candidates fill out a short form that slides in from the right side of the job listing page. No redirects, no new pages.

Application Panel - Slide-in Form

Before You Apply

You can apply as a guest (no account required) or as a registered candidate.

Registered candidates get:

  • A dashboard to track all their applications
  • Saved application history
  • Email updates on every status change

How to Apply

  1. Open a job listing page
  2. Click Apply Now - an application panel slides in from the right
  3. Fill in the form fields
  4. Click Submit Application

Application Form Fields

Field Requirement
Full Name Required (pre-filled if logged in)
Email Address Required (pre-filled if logged in)
Cover Letter Optional - but strongly recommended
Select Resume Choose from your saved resumes (Pro)
Upload Resume Upload a PDF, DOC, or DOCX file - max 5 MB

When Pro is active, you'll see both options: pick an existing resume from your profile or upload a file directly. The "- or upload a file -" divider separates the two methods.

With WP Career Board Pro: employers can also add custom screening questions to each job.

What Happens After You Apply

  1. You receive a confirmation email with the job title and company name
  2. The employer receives a notification email about your application
  3. Your application appears in your Candidate Dashboard → My Applications with status Submitted
  4. Get notified about similar jobs - after submitting, you'll see a prompt to create a job alert based on this job's category, type, and location (Pro feature)

Withdrawing an Application

If you change your mind:

  1. Go to your Candidate Dashboard → My Applications
  2. Find the application you want to withdraw
  3. Click Withdraw

Withdrawing permanently deletes the application. It is removed from both your dashboard and the employer's view. You cannot resubmit after withdrawing.

Application Limits

There is no limit to how many jobs a candidate can apply for on the free version.

Applying Without an Account

Guest applicants (no account):

  • Enter their name and email in the application form
  • Receive email confirmation
  • Cannot track their application status (no dashboard access)
  • Cannot withdraw their application

To track your application status, register as a candidate before applying.

My Applications

The My Applications tab in the Candidate Dashboard shows every job you have applied for and its current status.

Candidate Dashboard - My Applications Tab

Accessing My Applications

  1. Go to the Candidate Dashboard page
  2. The My Applications tab is active by default
  3. You will see all your applications listed newest first

Table format (1.2.0+)

Starting with 1.2.0, the block and its matching shortcode ([wcbp_my_applications]) render as a semantic table with column headers, so the data is screen-reader friendly and copy/paste-able into a spreadsheet without losing structure:

My Applications table - candidate view

Column What it shows
Job Job title (linked to the listing) and company name
Status Coloured status badge - see the table below for each badge's meaning
Submitted Application date in your site's date format

On narrow viewports (under 480px container width) the table collapses to a card layout - each row's cells stack vertically with their column label in-place, so phones get the same data without a horizontal scrollbar.

What You See per Application

Each row shows:

  • Job title and company name
  • Application date
  • Current status - updated by the employer
  • A link to view the original job listing

Application Statuses

Status What It Means
Submitted Your application was received; the employer hasn't reviewed it yet
Reviewing The employer is actively looking at your application
Shortlisted You're being considered - the employer is interested
Rejected The employer is no longer considering your application
Hired Congratulations - you got the job

Status updates: You will receive an email notification whenever your application status changes.

Withdrawing an Application

To withdraw from a role you are no longer interested in:

  1. Find the application in the list
  2. Click the Withdraw button
  3. Confirm in the prompt

Withdrawing permanently deletes the application. It is removed from both your dashboard and the employer's view. You cannot resubmit after withdrawing.

Overview Panel

The Overview tab at the top of the dashboard shows a summary of your recent activity:

  • Total applications submitted
  • Number of shortlisted applications
  • 4 most recent applications
  • Recently saved jobs

This gives you a quick snapshot without switching between tabs.

Saved Jobs

Save any job listing to your personal list so you can come back to apply when ready.

Candidate Dashboard - Saved Jobs Tab

Saving a Job

You can bookmark a job from two places:

From the job listings grid:

  • Click the bookmark icon in the top-right corner of any job card

From the job detail page:

  • Click the Save Job button on the listing page

Both require you to be logged in as a candidate. If you are not logged in, clicking the bookmark will prompt you to register or log in.

Viewing Your Saved Jobs

  1. Open the Candidate Dashboard
  2. Click the Saved Jobs tab

You will see all your bookmarked jobs listed with:

  • Job title and company name
  • Location and job type
  • Date saved
  • A Remove button

Removing a Saved Job

Click Remove on any saved job to delete it from your list. This does not affect any application you may have already submitted.

Applying from Saved Jobs

Saved jobs include a direct Apply Now link so you can apply without going back to the main listings page.

Tip: Use Saved Jobs as your personal shortlist. Browse the board first, bookmark the ones that interest you, then review your list and apply to the best matches.

Limit

There is no limit to how many jobs you can save.

Resume Builder

Pro feature - Requires WP Career Board Pro.

The Resume Builder lets candidates create structured, multi-section resumes directly on your WordPress site - no PDF uploads, no external tools required.

Resume Builder - Full View

What Candidates Can Build

A resume is made up of sections. Each section holds structured entries:

Section What it stores
Professional Summary A free-text overview paragraph
Work Experience Job title, company, dates, description
Education Degree, institution, dates
Skills Skill name and optional proficiency level
Languages Language name and proficiency
Certifications Certificate name, issuing body, date
Links Portfolio, GitHub, LinkedIn, etc.

Admin Setup

Before candidates can use the Resume Builder, set it up in two steps:

  1. Create a page and add the Resume Builder block to it
  2. Go to WP Career Board → Settings → Pages and assign that page to the Resume Builder Page field

Once assigned, the Candidate Dashboard's My Resumes tab will link to this page automatically.

My Resumes Tab

Candidates access their resumes from Candidate Dashboard → My Resumes.

My Resumes Tab - Dashboard

From this tab, candidates can:

  • See all saved resumes with their last-updated date
  • Click Edit to open a resume in the builder
  • Click Create New Resume to start a new one
  • Click Delete to permanently remove a resume

Using the Resume Builder

The builder is organized into collapsible sections. Click any section header to expand it.

Resume Builder - Sections

Adding Entries

  1. Open any section (e.g., Work Experience)
  2. Click + Add Entry
  3. Fill in the fields
  4. Click Save on the entry

The entry appears as a compact row. Click it to expand and edit again.

Entry Fields

Work Experience: Job Title, Company, Start Date, End Date, "Currently working here" toggle, Description

Education: Degree / Qualification, Institution, Start Year, End Year, Field of Study

Skills: Skill name, Proficiency level (Beginner / Intermediate / Advanced / Expert)

Languages: Language name, Proficiency (Native / Fluent / Conversational)

Certifications: Certificate name, Issuing organization, Issue date

Links: URL, Label (e.g., "Portfolio", "GitHub")

Auto-Save

The Resume Builder saves each entry individually when you click Save on that entry. There is no global save button. A "Saved" confirmation briefly appears after each save.

Multiple Resumes

Candidates can create more than one resume - for example, one for engineering roles and one for management roles. The dashboard lists all resumes with their last-updated date.

Attaching a Resume to an Application

When a candidate applies for a job, they can select one of their saved resumes to attach. The employer sees the full structured resume on the application - not a PDF attachment.

Resume Visibility

  • Private (default) - visible only to the candidate and employers who receive applications from them
  • Public - visible in the Find Resumes employer archive

Candidates toggle visibility in the Resume Builder header.

Job Alerts

Pro feature - Requires WP Career Board Pro.

Job Alerts let candidates subscribe to saved searches and receive email notifications when new matching jobs are posted. Candidates set a frequency - instant, daily, or weekly - and WP Career Board sends digests automatically.

Three Ways to Create Alerts

1. From the Job Listings Page

When browsing jobs, click the "Alert me" button in the toolbar (next to the results count). This saves your current search query and active filters as a daily alert.

The button turns into "Alert saved" with a green checkmark to confirm.

2. After Applying for a Job

After submitting an application, you'll see a "Get notified about similar jobs" button below the success message. Clicking it creates an alert based on the job you just applied to - matching its category, type, and remote status.

3. From the Candidate Dashboard

Go to Candidate Dashboard → Job Alerts to view and manage all your alerts. From here you can also adjust the frequency of each alert.

Alert Frequency Options

Frequency When the email sends
Instant As soon as a matching job is posted
Daily Once per day (morning digest)
Weekly Once per week (Monday morning)

You can change the frequency at any time from the dashboard.

What Gets Matched

Alerts match new jobs against these criteria:

  • Keywords - job title contains your search terms
  • Category - job is in the same category
  • Job Type - full-time, part-time, contract, etc.
  • Location - matches the location taxonomy
  • Salary Range - job salary falls within your range
  • Remote - remote-only filter

Managing Alerts

From Candidate Dashboard → Job Alerts:

  • View all active alerts with their saved filters shown as pills
  • Change frequency using the dropdown (Instant / Daily / Weekly)
  • Delete an alert with the Delete button

The nav badge shows your total alert count.

Overview Stats

Your alert count also appears on the Dashboard Overview page alongside your Applications, Saved Jobs, and Resumes counts. Click the Job Alerts stat card to jump directly to the alerts tab.

Email Delivery

Alert emails are sent via the Notifications settings configured in WP Career Board → Settings → Notifications (From Name, From Email). Configure an SMTP plugin for reliable delivery.

Salary Range Filter

The Find Jobs page (/jobs/) now ships a salary range slider so candidates can narrow listings to roles paying within a specific range - instead of scanning every salary line manually.

Where it lives

On the Find Jobs page, in the filter panel below the search bar. The slider appears alongside the existing filters (location, job type, experience, category).

How it works

  • Drag the lower handle to set a minimum salary.
  • Drag the upper handle to set a maximum salary.
  • The active range shows as a chip pill above the listings - e.g. $60k-$120k/yr ✕. Click the ✕ to clear that filter.
  • Active range updates the listings live (no page reload).

The slider's range adapts to the salary distribution of currently listed jobs, so on a small board the slider tracks $0-$100k while on a senior-only board it might track $80k-$300k.

Periods

The slider respects whichever salary period each job is using - yearly, monthly, or hourly. Jobs without salary data are filtered out when the salary slider is active (set the slider to its widest range to include them again).

Currency

The slider currency follows the site's default currency (configurable in the Career Board → Settings → Currency tab). Multi-currency boards still display each job in its own currency, but the filter applies the comparison after a normalized conversion.

REST equivalent

If you're driving listings programmatically:

GET /wp-json/wcb/v1/jobs?salary_min=60000&salary_max=120000

Both bounds are optional. Omit salary_max for "$60k+" listings; omit salary_min for "up to $120k" listings.

On mobile

The slider stacks below the search bar and uses a touch-friendly grip. The chip pill remains tap-to-clear.

Apply as a Guest

You can now apply to a job without creating an account first. The apply form on every job page accepts:

  • Your name + email
  • A cover letter (optional)
  • A resume file upload (PDF / DOC / DOCX)

This makes it easy to apply on the spot - no signup wall.

How to apply as a guest

  1. Open any job page (e.g. /jobs/senior-backend-engineer/).
  2. Click Apply Now.
  3. The apply panel opens - fill in your name + email.
  4. Drop a resume file into the Click to upload resume zone, or pick one with the file picker. PDF, DOC, and DOCX accepted, up to the size cap configured by the site (default 5 MB, sites can raise to 20 MB).
  5. (Optional) Write a cover letter in the Cover Letter (optional) textarea.
  6. Click Submit Application.

The employer receives the application instantly. They see your name, email, cover letter, and resume preview from their dashboard.

Required vs optional resume

Whether a resume is required depends on the site's settings:

  • Resume required (default for new sites since 1.1.0) - you must attach a file to submit.
  • Resume optional - you can submit without a file. The employer may follow up via email.

If a site requires a resume but you try to submit without one, you'll see a clear error message: "A resume is required to apply for this job." Drop a file and resubmit.

Privacy

Your application is stored against your email address. If you later create an account using the same email, the system will link your historical guest applications to the new account automatically - your "My Applications" page will show them.

If you'd like a copy of your data or want it deleted, the Privacy & My Data controls in the candidate dashboard handle GDPR self-service requests.

File format support

Format Accepted Note
PDF Recommended - preserves layout for the employer
DOC Older Word format
DOCX Modern Word format
ODT, RTF, TXT Not currently supported. Save as PDF first.
Image (JPG / PNG) Photos of resumes are rejected - convert to PDF

What happens after submit

You'll see a confirmation message inline: "Application submitted - the employer will be in touch." That's it. No further account-creation steps unless you want to track applications going forward.

Troubleshooting (Candidates)

Common things candidates run into, with the practical fix for each. If you're an employer, see for-employers/12-troubleshooting.md.

"I applied but never heard anything back"

That's almost always normal - most employers review applications in batches. Check Candidate Dashboard → My Applications to verify your application is there.

  • Status "Submitted" - the employer has it, hasn't acted yet. No action from you needed.
  • Status "Reviewing" - they've looked at it.
  • Status "Shortlisted" - you're under consideration. Expect follow-up.
  • Status "Hired" - congratulations, you got the job.
  • Status "Rejected" - not a fit for this role; the application is closed.
  • Status "Withdrawn" - you (or the system) withdrew it.
  • Status "Job Removed" - the job posting was taken down. Your application is preserved in your history but no further action is expected.

If you don't see the application at all in your dashboard, it didn't submit successfully - try again.

"The Apply button is missing from a job"

Two reasons this happens:

  1. You need to log in. Many sites require a candidate account to apply. Register from the Candidate Dashboard if you don't have one.
  2. The job's deadline has passed. Expired jobs hide the apply button. Look for the deadline date on the job page.

"I can't apply - it says 'You have already applied'"

You already submitted to this job. Two ways this happens:

  • You applied as a guest with the same email. The system blocks duplicate guest applications to the same job within 24 hours. If you really want to send a different application, register an account and apply from there.
  • You applied as a logged-in candidate. Each candidate can apply once. Withdraw the existing application (from your dashboard) if you want to re-apply with a different resume.

"My resume upload failed"

  • File too large. Default limit is 5 MB. Re-export your PDF with smaller image embeds.
  • Wrong format. PDF works on every site. Word docs (.docx) may or may not, depending on site config - convert to PDF if in doubt.
  • Network blip. Re-try the upload. Don't hit "Apply" again until the upload completes.

"I can't find a job I saw earlier"

  • It might have expired. Default listing hides past-deadline jobs. Use the search bar to find it by title - expired jobs may still be searchable in some configurations.
  • It might have been deleted. If the employer pulled the posting, it's gone.
  • You bookmarked it. Check Candidate Dashboard → Saved Jobs - bookmarks survive even if the job changes status.

"My saved jobs aren't showing up"

  • Make sure you're logged in. Bookmarks are tied to your account; they don't survive logout if you're using a guest session.
  • The bookmark might not have saved. Try clicking the bookmark button again. The button highlights when the job is saved.

"I didn't get the confirmation email after applying"

  • Check your spam / promotions folder. Most missing emails are spam-flagged.
  • The site might have email-sending issues. This is a site-admin problem, not yours - your application IS still recorded (verify in your dashboard).
  • Wrong email on file. If you applied as a guest with a typo in your email, the confirmation went to the wrong address. The application is recorded but you have no way to track it. Register an account and apply again with the right email.

"I see 'Job no longer available' on one of my applications"

The employer (or a site admin) deleted that job posting after you applied. Your application is preserved in your history - that's intentional, so you have a record of having applied. The status moves to "Job Removed" so you know it's no longer in flight.

If you'd been hired or shortlisted before the deletion, the employer typically reaches out separately. If you weren't yet, the role won't move forward through this posting - they may re-post later, or they may have filled it through another channel.

"I'm getting too many job alerts (or too few)"

  • Manage your alerts at Candidate Dashboard → Job Alerts. Each alert has a keyword, location, and frequency you can edit or delete.
  • Email frequency is per-alert: daily or weekly. If you set up multiple alerts overlapping in keywords, you'll get multiple emails - consolidate them.

"My profile says I'm 'Open to Work' but I'm not getting contacted"

The "Open to Work" flag makes you discoverable to employers searching candidates. To improve visibility:

  • Complete your profile - add a job title, location, skills, and a real resume. Empty profiles rank low in searches.
  • Update the skills section. Employers search by skill tags, and "JavaScript" matches more searches than "JS" or "Frontend".
  • Add a clear resume PDF. Employers ignore profiles without an attached resume.

"I forgot my password"

Use the standard WordPress "Lost password" link on the login page. You'll get a reset email at the address you registered with.

"I want to delete my account"

Candidate Dashboard → Profile → Delete my account. This triggers a confirmation email; click the link to permanently delete:

  • Your account
  • All your applications (the employers see "Anonymous candidate" on archived applications, not your details)
  • Your resume(s)
  • Your saved jobs and alerts

This is a GDPR / privacy compliant erasure - it cannot be undone once the confirmation link is clicked.

I'm stuck - who do I contact?

Look on the site for a "Contact" link, usually in the footer. When you reach out, include:

  1. The URL of the page where the problem happens.
  2. A screenshot of what you see.
  3. The time and date.
  4. The email address tied to your account.

Don't include passwords, payment info, or sensitive personal data - just descriptive details.

Related

Admin Guide

Site-owner configuration: settings, moderation, email, GDPR, custom fields.

Settings

Configure WP Career Board from WP Career Board → Settings in wp-admin. Settings are organized into tabs.

Settings Page - Job Listings Tab

Job Listings Tab

Controls how jobs behave on your board.

Setting Default Description
Auto-Publish Jobs Off When on, submitted jobs go live immediately without admin approval
Jobs Per Page 10 Number of jobs shown per page in the listings grid
Job Expiry (days) 30 Jobs close automatically after this many days; 0 = no expiry
Deadline Auto-Close Off Automatically closes jobs when their application deadline passes
Allow Withdraw Off Lets candidates withdraw their own applications
Default Salary Currency USD Site-wide default currency for new job postings; employers can override per job

Pages Tab

Links each feature to its dedicated page. If the Setup Wizard ran successfully, these are filled in automatically.

Setting Purpose
Jobs Archive Page The main job board browse page (Find Jobs)
Employer Dashboard Page The employer's management page
Candidate Dashboard Page The candidate's tracking page
Company Archive Page The public company directory

If a page assignment is blank, the related functionality (e.g., "View your dashboard" links in emails) won't work correctly. Always fill these in.

With WP Career Board Pro: a "Resume Builder Page" setting is also shown here.

Notifications Tab

Controls the sender name, from email, and admin notification email address used by all WCB emails. See Email Notifications for the full guide.

Emails Tab

Lets you enable or disable each individual email notification and customize its subject line and body. See Email Notifications for placeholders and customization options.

Import Tab

One-click migration from WP Job Manager. See Import & Migration for the full guide.

Antispam Tab

Configure reCAPTCHA v3 for job application and registration forms. Enter your reCAPTCHA Site Key and Secret Key to enable bot protection.

Pro-Only Tabs

When WP Career Board Pro is active, seven additional tabs appear:

Tab What It Controls
Resumes Resume visibility, file upload, and resume builder settings
Boards Multi-board engine: create and manage independent job boards; pipeline stages are configured within this tab
Field Builder Custom fields for jobs, companies, and candidates
Credits Credit settings, product-to-credit mappings, detected payment providers, and credits-per-job-post value
AI Settings Configures the AI provider key for AI Chat Search and job description generation
Job Feed RSS/JSON feed settings for job listing aggregators
Integrations Third-party service connections and API integrations
License Pro license key activation and management

Saving Settings

Click Save Changes at the bottom of any tab. Settings are saved per-tab - you don't need to switch tabs before saving.

Email Notifications

WP Career Board sends automatic emails for key events. All emails use WordPress's built-in wp_mail() function and are fully customizable.

Email Notifications Settings

Notification Events

Email Sent To Trigger
New Job Pending Review Admin Employer submits a new job
Job Approved Employer Admin approves a pending job
Job Rejected Employer Admin rejects a pending job
Job Expired Employer Job reaches its expiry date
Application Received Employer Candidate applies to their job
Application Confirmation (Candidate) Candidate Registered candidate submits an application
Application Confirmation (Guest) Guest Guest applicant submits an application
Application Status Changed Candidate Employer updates application status (Reviewing, Shortlisted, Rejected, Hired)

Managing Notifications

Go to WP Career Board → Settings → Emails.

Each notification can be:

  • Enabled or disabled - toggle the switch to turn it on or off
  • Customized - edit the email subject and body text

Click the email name to expand the editor for that notification.

Send Test Email

Each template ships with a Send test button on the right of the row. Clicking it dispatches a one-shot copy of that email to the admin user's address with sample merge-tag values, so you can preview the rendered template before any real applicant sees it.

Send test email button in the Sent state

The button works for both enabled and disabled templates - disabled templates are still rendered and dispatched for preview, but their log rows are tagged sent_test in the activity log so admin previews stay separate from production delivery metrics. A green check + "Sent" label appears for 2.5 seconds after a successful dispatch, then resets.

If the button shows "Failed", check:

  • An SMTP plugin is configured (the local dev mail handler often fails silently)
  • The admin user has a valid email address on their profile
  • The Email Activity Log row says sent_test for the most recent attempt - if the row is missing, see the self-heal note below

Email Placeholders

Use these placeholders in email subjects and bodies - they are replaced with real values when the email sends:

Placeholder Value
{job_title} The job listing title
{company_name} The employer's company name
{candidate_name} The applicant's full name
{application_status} Current status of the application
{dashboard_url} Link to the employer or candidate dashboard
{job_url} Link to the job listing page
{site_name} Your WordPress site name

Email From Name and Address

Go to WP Career Board → Settings → Notifications to set:

  • From Name - the sender name shown in inboxes (e.g. "Career Board")
  • From Email - the reply-to address for all WCB emails
  • Admin Notification Email - where admin alerts (e.g. new job pending review) are sent

SMTP / Deliverability

For reliable email delivery, use an SMTP plugin (WP Mail SMTP, FluentSMTP, or similar). WordPress's built-in mail function can land in spam without SMTP configuration.

Email Activity Log {#email-activity-log}

Every dispatched email writes a row to wp_wcb_notifications_log and surfaces on the Activity Log tab at the bottom of Settings → Emails. Rows show the event type, channel, recipient, status (sent / failed / sent_test / failed_test), and timestamp.

The log table is created on plugin activation. If for any reason the table is missing (e.g. a database migration dropped it, or the plugin was installed pre-1.0.x and skipped the activation routine), the dispatch path self-heals the table on first send rather than failing silently - your previously missing log entries will start populating from the next dispatch onward.


Pro Email Notifications (Pro)

WP Career Board Pro extends the email system with three additional transactional emails. You can customise the subject line and enable or disable each one from Career Board -> Settings -> Emails.

Job Alert Digest

  • Recipient: Candidate
  • Trigger: Fired when the Job Alerts module finds new jobs matching a candidate's saved search
  • Content: A list of matching job titles with direct links

Credit Top-Up Confirmation

  • Recipient: Employer
  • Trigger: When a credit purchase completes via a supported payment gateway (WooCommerce, Paid Memberships Pro, or MemberPress)
  • Content: Confirmation of the purchase and updated balance

Low Credit Balance Warning

  • Recipient: Employer
  • Trigger: Fired when an employer's credit balance reaches zero
  • Content: Balance warning and a link to the Employer Dashboard to purchase more credits

Email Template Customisation

All Pro emails use the same templating system as Free emails. To override a template, copy the relevant file from modules/notifications-pro/templates/emails/ into your theme's woocommerce/ folder or use the wcb_email_template_dirs filter to add a custom template directory.

In-App Notification Bell (Pro)

The notification bell appears in the Employer Dashboard and Candidate Dashboard. It shows a live unread count and drops down to display a list of recent notifications, each with a message and a link to the relevant page.

Events That Trigger Bell Notifications

Event Who Receives It Message Example
Application submitted Employer "Jane Doe applied for Senior PHP Developer"
Application submitted Candidate "Your application for Senior PHP Developer was submitted"
Application status changed Candidate "Your application for Senior PHP Developer is now Shortlisted"
Job approved Employer "Your job 'Senior PHP Developer' has been approved"
Job rejected Employer "Your job 'Senior PHP Developer' was not approved"
Job expired Employer "Your job 'Senior PHP Developer' has expired"

All notifications are stored in the wcb_notifications database table. The is_read flag is set to 0 on insert. The bell badge count reflects the number of unread rows for the current user.

Deadline reminders {#deadline-reminders}

New in 1.1.0 - candidates who saved a job but haven't applied get automated reminders before the application deadline closes.

Reminder schedule

When Email
3 days before the deadline "Your saved job is closing soon" reminder
1 day before the deadline "Last chance to apply" final reminder

Both reminders are skipped if:

  • The candidate has already submitted an application for that job, OR
  • The candidate has un-saved the job, OR
  • The job has been closed / removed before the cron fires.

Cron event

Registered as wcb_send_deadline_reminders, runs daily.

WordPress's wp-cron triggers it on the next page load after the scheduled time - for low-traffic sites, install a real cron job that hits wp-cron.php to keep timing accurate.

To trigger manually:

wp cron event run wcb_send_deadline_reminders

Disabling deadline reminders

Navigate to Career Board → Settings → Email and uncheck Send application deadline reminders. The cron stays scheduled (so re-enabling is one click) but skips the dispatch loop.

To disable the cron entirely (for example, on staging environments):

add_filter( 'wcb_cron_disabled_hooks', function( $hooks ) {
    $hooks[] = 'wcb_send_deadline_reminders';
    return $hooks;
} );

Email template

Standard plugin email format with the configured logo, header/footer. Subject line: "Your saved job '{{job_title}}' closes in {{days}} days".

Custom merge tags available:

Tag Value
{{candidate_name}} Candidate first name
{{job_title}} Title of the saved job
{{company_name}} Company that posted the job
{{deadline_date}} Localized deadline date
{{days}} Days until deadline
{{job_url}} Direct link to the job page

Override the template by copying modules/notifications/templates/emails/deadline-reminder.php into your theme's wp-career-board/emails/ folder.

Moderation

Moderation controls whether jobs need admin approval before they go live. It prevents spam and low-quality listings on your board.

How Moderation Works

When Auto-Publish Jobs is turned off (the default), every job submitted by an employer goes to a Pending state and must be approved by an admin before it appears on the job board.

When Auto-Publish Jobs is turned on, submitted jobs go live immediately without review.

To toggle moderation: WP Career Board → Settings → Job Listings → Auto-Publish Jobs

Reviewing Pending Jobs

  1. Go to WP Career Board → Jobs in wp-admin
  2. Click the Pending filter at the top of the list
  3. Click any job title to open the full edit screen and review the content

Admin Jobs - Pending Filter

Approving a Job

Quick approval (from the list):

  1. Hover over the job in the list
  2. Click Approve under the title

Full review (from the edit screen):

  1. Open the job in the wp-admin editor
  2. Review all details
  3. Change the status to Published in the Post Status panel
  4. Click Update

When a job is approved, the employer receives an email notification.

Rejecting a Job

  1. Open the job in the wp-admin editor
  2. Change the status to Draft or Trash
  3. Optionally email the employer with a reason (done manually outside the plugin)

Managing Existing Jobs

Admins have full control over all jobs from WP Career Board → Jobs:

  • Edit any job (correct errors, add missing info)
  • Close a job that is running too long
  • Delete spam or low-quality listings

Admin Notifications

Admins receive a New Job Pending Review email when an employer submits a job for approval. This is the only admin-facing email notification. Notification content can be customized in Settings → Emails.

GDPR & Privacy

WP Career Board integrates with WordPress's built-in privacy tools to help you comply with GDPR and similar data protection regulations.

What Data WP Career Board Stores

Per employer:

  • Company name, logo, description, website, size, industry
  • Posted job listings

Per candidate:

  • Name and email address
  • Cover letters submitted
  • Application history and status

System logs:

  • Application timestamps

Data Export

WordPress has a built-in personal data export tool. WP Career Board integrates with it so all job board data for a user is included.

To export a user's data:

  1. Go to Tools → Export Personal Data in wp-admin
  2. Enter the user's email address
  3. Click Send Request
  4. The user receives an email with a link to download their data export

The export includes all applications, cover letters, and profile data associated with that email address.

Data Erasure

To erase a user's personal data:

  1. Go to Tools → Erase Personal Data in wp-admin
  2. Enter the user's email address
  3. Click Send Request
  4. The user confirms via email
  5. After confirmation, WordPress erases all personal data including WP Career Board records

Note: Erasing a user's data removes their applications and profile. Job listings posted by an employer are not automatically deleted - you may need to manually remove those.

Privacy Policy Page

Add the following to your privacy policy to inform users what data WP Career Board collects:

  • Account registration data (name, email)
  • Job applications including cover letters
  • Activity logs for job board interactions
  • No payment data is stored (payments are processed by your e-commerce plugin - WooCommerce, PMPro, or MemberPress - not by WP Career Board directly)

Cookie Usage

WP Career Board does not set any cookies in the free version. Session state (e.g., active dashboard tab) is stored in sessionStorage (browser memory only, not a cookie, cleared when the browser tab closes).

Custom Field Builder

Pro feature - Requires WP Career Board Pro.

The Field Builder lets you add custom fields to job listings, company profiles, and candidate profiles - no code required. Fields appear automatically in the relevant forms and public pages.

Field Builder - Admin Interface

What You Can Add

  • Fields to job listings - e.g., Remote Policy, Visa Sponsorship, Tech Stack
  • Fields to company profiles - e.g., Funding Stage, Team Size, Benefits
  • Fields to candidate profiles - e.g., Notice Period, Preferred Work Style, Portfolio URL

Accessing the Field Builder

Go to Career Board → Settings → Field Builder in wp-admin.

You will see three tabs:

  • Job Fields - fields added to job listings
  • Company Fields - fields added to company profiles
  • Candidate Fields - fields added to candidate profiles

Creating a Field Group

Fields are organized into groups - collapsible sections with a label (e.g., "Compensation Details").

  1. Click Add Group
  2. Enter a group label
  3. Click Save Group

You can create multiple groups to organize related fields.

Adding a Field

  1. Expand the group where you want to add the field
  2. Click + Add Field
  3. Configure the field:
Setting Description
Field Label The label shown on the form and public page
Field Type Text, Textarea, Number, Select, Checkbox, Date, URL, File Upload
Required Whether the field must be filled in
Visibility Public, Logged In Only, Employer Only, Candidate Only
Placeholder Hint text shown inside the input
Options The choices available (for Select and Checkbox fields)
  1. Click Save Field

Adding a Custom Field

Field Types

Type Use for
Text Short values - tech stack, notice period, LinkedIn URL
Textarea Longer text - benefits overview, culture note
Number Salary, team size, years of experience
Select Single-choice dropdown - Remote Policy, Visa Sponsorship
Checkbox Group Multiple choices - Benefits, required skills
Toggle Single on/off - "Visa sponsorship available?"
Date Application deadline, estimated start date
URL Portfolio, GitHub, external job link
File Upload Attach a PDF, document, or image

Visibility Rules

Each field can be set to:

  • Public - visible to all visitors including guests
  • Logged in only - visible to registered users only
  • Employer only - visible only to employers (e.g., on the job form)
  • Candidate only - visible only to candidates

Reordering

Drag and drop fields within a group to reorder them. Drag and drop groups to change their order. Changes save automatically.

Deleting a Field

Click Delete on any field. This permanently removes the field and all stored values across all posts. This cannot be undone.

Where Fields Appear

Field Type Appears in Displayed on
Job Fields Multi-step Job Form Job single page
Company Fields Company Profile editor Public company page
Candidate Fields Candidate profile settings Candidate profile

Import & Migration

WP Career Board includes a built-in migration tool to import jobs and resumes from WP Job Manager. Access it from WP Career Board → Settings → Import.

Import Page

Overview

The importer reads data from WP Job Manager's post types (job_listing, resume) and creates equivalent WCB records (wcb_job, wcb_resume). Your original WP Job Manager data is never modified or deleted.

The import uses REST API calls (POST /wcb/v1/import/run) batched in groups, with a live progress bar so large imports don't time out.

Idempotent - Safe to Re-Run

Every migration checks for an existing WCB record before importing. Records already imported are automatically skipped. You can run the import multiple times without creating duplicates.

Available Migrations

WP Job Manager → Jobs (Free)

Migrates job_listing posts to wcb_job. Available in the free plugin.

Fields migrated:

WP Job Manager field WCB equivalent
Title & description Job title + post content
_job_location _wcb_location + location taxonomy
_job_salary _wcb_salary_min / _wcb_salary_max
Salary currency & pay type _wcb_salary_currency / _wcb_salary_type
_job_expires / _job_duration _wcb_deadline
_featured _wcb_featured
_remote_position _wcb_remote
_application (email or URL) Preserved as application meta
_company_name, _company_website, _company_tagline, _company_twitter, logo, video Company profile meta
_filled → closed Post status mapped to Closed
job_cat, job_type taxonomies wcb_category, wcb_job_type

How to run:

  1. Go to WP Career Board → Settings → Import
  2. The card shows how many WP Job Manager jobs were found and how many are already imported
  3. Click Import All Jobs
  4. A progress bar shows batch-by-batch progress until complete

WP Job Manager does not need to remain active after the import is complete.

WP Job Manager Resumes → Resumes (Pro)

Pro feature - Requires WP Career Board Pro.

Migrates resume posts to wcb_resume. Only available when WP Career Board Pro is active.

Fields migrated:

WP Job Manager Resumes field WCB equivalent
Candidate name & bio Resume title + summary
Professional title Resume headline
Contact email Candidate email
Location Resume location
Photo Candidate avatar
Video URL Resume video link
Resume file attachment Attached file
_featured Featured flag
_resume_expires Expiry date
Education history Education section entries
Work experience Work Experience section entries
Social / website links Links section entries
resume_category Resume categories

How to run:

  1. Go to WP Career Board → Settings → Import
  2. The WP Job Manager Resumes card is shown when Pro is active
  3. Click Import All Resumes
  4. Monitor the progress bar until complete

What Happens with Duplicates

Each import run checks whether a WCB record already exists for a given WP Job Manager post ID (tracked via the _wcb_migrated_from meta key). If it does, that record is skipped and counted as "already imported" - not re-imported or overwritten.

Progress Display

The Import page shows live stats for each migration:

Stat Meaning
Found Total records in WP Job Manager
Already imported Records already migrated to WCB
Remaining Records that will be processed on the next run

After Importing

  1. Go to WP Career Board → Jobs to review imported jobs - check statuses and verify key fields
  2. Go to WP Career Board → Settings → Pages and confirm page assignments are correct
  3. Flush your permalink structure via Settings → Permalinks → Save Changes
  4. If WP Job Manager had categories or job types that don't map cleanly, review them in WP Career Board → Job Categories and WP Career Board → Job Types

Limitations

  • Custom fields added by WP Job Manager extensions are not automatically mapped - you will need to re-enter those manually
  • Applications submitted in WP Job Manager are not migrated (no equivalent structure in the free plugin)
  • The importer does not delete WP Job Manager data after migration - you can deactivate and delete WP Job Manager separately once you are satisfied with the results

Credit System (Pro)

Pro feature - Requires WP Career Board Pro.

The Credit System lets you charge employers credits to post jobs. Credits are purchased through your existing e-commerce plugin - WooCommerce, Paid Memberships Pro, MemberPress, or WooCommerce Subscriptions - and deducted automatically when jobs go live.

How It Works

  1. Admin creates a product - create a WooCommerce product (or PMPro plan, MemberPress membership) that represents a credit package
  2. Admin maps product to credits - in Settings → Credits, map that product to a credit amount (e.g., "10 Job Posting Credits" product = 10 credits)
  3. Employer buys credits - purchases the product through your shop using any payment gateway (Stripe, PayPal, Square, etc.)
  4. Credits added on purchase - when the order completes, credits are automatically added to the employer's balance
  5. Credits held on submit - when the employer submits a job, the required credits are reserved
  6. Credits deducted on approval - when the job goes live, credits are consumed
  7. Refund on rejection - if the admin rejects a job, held credits are returned

Credit Ledger

Every transaction is logged in an append-only audit trail:

Type Effect
Top-up Credits added (from a purchase or manual adjustment)
Hold Credits reserved (job submitted, awaiting approval)
Deduct Credits consumed (job approved and live)
Refund Credits returned (job rejected or cancelled)

Supported Payment Providers

WP Career Board Pro uses the Wbcom Credits SDK with adapters for each payment provider. The Credits tab automatically detects which plugins are active on your site:

Provider Plugin Required How Credits Are Triggered
WooCommerce WooCommerce (free) Order status changes to "completed"
WooCommerce Subscriptions WooCommerce Subscriptions Credits added on each subscription renewal
Paid Memberships Pro Paid Memberships Pro Credits added when a membership level is activated
MemberPress MemberPress Credits added when a membership transaction completes

You can use any payment gateway supported by your chosen provider - Stripe, PayPal, bank transfer, or anything else the provider supports. WP Career Board does not process payments directly.

Step 1: Create a Credit Product

WooCommerce (recommended)

  1. Go to Products → Add New in wp-admin
  2. Set the product name (e.g., "10 Job Posting Credits")
  3. Set the product type to Simple product
  4. Set a price (e.g., $79.00)
  5. In the product description, explain what the employer gets
  6. Publish the product

Repeat for each credit tier you want to offer:

Product Name Price Credits (mapped in Step 2)
Starter - 3 Credits $29 3
Growth - 10 Credits $79 10
Agency - 25 Credits $149 25

For WooCommerce Subscriptions, create a subscription product instead. Credits will be added on each renewal, giving employers a recurring credit allowance.

Paid Memberships Pro

Create a membership level that represents a credit tier. When an employer activates that membership level, credits are added based on your mapping in Step 2.

MemberPress

Create a membership that represents a credit tier. When the membership transaction completes, credits are added based on your mapping in Step 2.

Step 2: Map Products to Credits

  1. Go to WP Career Board → Settings → Credits
  2. Under Credit Mappings, click Add Mapping
  3. Select your WooCommerce product (or PMPro level, MemberPress membership) from the dropdown
  4. Enter the number of credits that product should grant
  5. Click Save Changes

Each product can map to a different credit amount. When an employer purchases that product and the order completes, the mapped number of credits is automatically added to their balance.

Step 3: Configure Credit Settings

In WP Career Board → Settings → Credits, configure:

Setting Description
Credits per Job Post How many credits are deducted when a job is approved. Set to 0 for free posting.
Low Balance Alert Threshold When an employer's balance drops to this number, they see a warning.
Credits Purchase URL The URL where employers are sent to buy more credits (typically your WooCommerce shop page or a dedicated credits page).

Detected Providers

The bottom of the Credits tab shows Detected Providers - a list of which payment plugins are currently active. If a provider is not shown, activate its plugin and refresh the page.

Employer Experience

Employers see their credit balance in:

  • The Employer Dashboard header
  • The Confirm & Submit step of the Job Form

When their balance is too low, they see a "Buy Credits" prompt linking to your configured Credits Purchase URL. The employer completes the purchase through your WooCommerce checkout (or PMPro/MemberPress registration) using whatever payment method you have configured.

Employer Dashboard - Credit Balance

The Hold → Deduct → Refund Cycle

  1. Hold - When an employer submits a job, the required credits are immediately reserved from their available balance. The employer cannot spend held credits on another job.
  2. Deduct - When the admin approves the job (or it auto-publishes), the held credits are permanently consumed.
  3. Refund - If the admin rejects the job, the held credits are returned to the employer's available balance.

This ensures employers are never charged for jobs that don't go live.

Admin Credit Adjustment

Admins can manually add or deduct credits for any employer:

  1. Go to WP Career Board → Employers
  2. Click the employer's name
  3. In the Credits section, enter the number of credits to add (or a negative number to deduct)
  4. Add an optional note (e.g., "Trial credits" or "Compensation for rejected job")
  5. Click Adjust Credits

Manual adjustments are recorded in the credit ledger with the admin's note, so there is always a clear audit trail.

Viewing the Credit Ledger

The full transaction history for any employer is visible from their admin profile - every top-up, hold, deduction, refund, and manual adjustment with timestamps and notes.

Troubleshooting & FAQ

Common issues and how to resolve them.


Setup Wizard

The wizard says "Failed to create pages" and won't advance

The wizard calls the WordPress REST API to create pages. This can fail when:

  • Pretty permalinks are off - go to Settings → Permalinks, select any option other than Plain, and save.
  • REST API is blocked - a security plugin, firewall, or hosting rule is blocking /wp-json/. Temporarily deactivate security plugins and try again.
  • Auth cookie not sent - if your site uses basic HTTP auth (common on staging), the REST request won't carry your session. Disable basic auth temporarily or add an exception for /wp-json/.

After fixing the underlying issue, go to WP Career Board → Settings → Run Setup Wizard to run the wizard again.


Pages were created but they're blank or show a 404

The pages were created but may not have the correct block assigned. Edit each page in the block editor and insert the matching block:

Page Block to insert
Find Jobs Job Search + Job Filters + Job Listings
Employer Registration Employer Registration
Employer Dashboard Employer Dashboard
Candidate Dashboard Candidate Dashboard
Companies Company Archive

Then go to Settings → Permalinks and click Save Changes to flush rewrite rules.


Jobs Not Appearing

The Job Listings block shows "No jobs found"

  1. Confirm you have published jobs - go to WP Career Board → Jobs and check the status column.
  2. If jobs are pending review, go to WP Career Board → Settings → Job Listings and check whether Auto-Publish Jobs is enabled. If off, you need to approve each job manually from the Jobs list.
  3. Check your active filters in the block - the Job Type, Category, or Location filters may be set to a value that returns no results.
  4. Go to Settings → Permalinks and click Save Changes to flush rewrite rules.

Jobs appear in wp-admin but not on the frontend

This is almost always a permalink flush issue. Go to Settings → Permalinks and click Save Changes.


Application Form

The "Apply" button does nothing / the application form doesn't open

  • Guest applications are supported by default - no setting needs to be enabled. If the form still doesn't open, check that the user's browser is not blocking JavaScript.
  • If using a page caching plugin (WP Rocket, W3 Total Cache), purge the cache after activating WP Career Board.
  • Check the browser console for JavaScript errors - a JavaScript conflict with another plugin can prevent the form from loading.

Candidates can't submit the application form

  • The job may have a deadline that has already passed. Check the job listing's deadline field.
  • If the job requires a resume upload and the candidate has no resume, the form will block submission. Check if Require Resume is enabled for that job type.
  • Make sure file upload limits in your hosting's php.ini (upload_max_filesize, post_max_size) are large enough for resume files (recommend at least 5 MB).

Email Notifications

Emails are not being sent

WP Career Board uses wp_mail() to send emails. If emails aren't arriving:

  1. Check spam - the notification emails from a local WordPress install often land in spam.
  2. Install an SMTP plugin - the default wp_mail() uses PHP's mail() function, which most shared hosts reject. Install an SMTP plugin (e.g. WP Mail SMTP, FluentSMTP) and connect it to a transactional email service (Mailgun, SendGrid, Postmark).
  3. Verify the sender address - go to WP Career Board → Settings → Notifications and confirm the From email matches your domain. Some hosts reject mail from mismatched domains.
  4. Check notification toggles - each notification type can be toggled off in Settings → Notifications. Confirm the relevant notification is enabled.

The wrong email address is receiving notifications

Admin notification emails go to the address set in Settings → Notifications → Admin Email. This defaults to the WordPress admin email but can be overridden.


Employer & Candidate Accounts

A user registered but isn't showing up as an Employer or Candidate

The role is assigned at registration based on which registration form the user used:

  • Employers register via the Registration page (which contains the unified Registration block).
  • Candidates register via the Registration page (which contains the unified Registration block).

If a user registered via the standard WordPress login page, they won't have a job board role. Go to WP Career Board → Employers or Candidates and manually assign the user.

An employer can't post jobs

  1. Check the employer's account in WP Career Board → Employers - confirm they have the Employer role.
  2. If the Credit System is active (Pro), confirm the employer has available credits. A zero balance blocks job posting.
  3. Confirm the employer can access the Employer Dashboard, where job posting is done.

Credit System (Pro)

Credits were purchased but not added to the employer's balance

Credits are added when the WooCommerce order status changes to "completed" (or the equivalent event for PMPro/MemberPress). If credits are missing after a purchase:

  1. Check order status - go to WooCommerce → Orders and confirm the order is marked "Completed", not "Processing" or "On Hold". Some payment gateways (e.g., bank transfer) leave orders in a non-completed state until manually updated.
  2. Check the credit mapping - go to WP Career Board → Settings → Credits → Credit Mappings and confirm the purchased product is mapped to a credit amount. If the product is not mapped, no credits are granted.
  3. Check Detected Providers - at the bottom of the Credits tab, confirm your payment plugin (WooCommerce, PMPro, or MemberPress) is listed as detected. If it is not shown, activate the plugin and refresh.
  4. Check the debug log - enable WP_DEBUG_LOG in wp-config.php and look for wcb_credits entries in wp-content/debug.log. The Wbcom Credits SDK logs all credit operations.
  5. Manual fix - go to WP Career Board → Employers, click the employer's name, and use Admin Credit Adjustment to manually add the missing credits with a note explaining the reason.

Employer says "Insufficient credits" but they just purchased

The employer's browser may be showing a cached page. Ask them to refresh the Employer Dashboard. If the issue persists, check the order status and credit mapping as described above.


Block Issues

The block editor shows "Your block contains unexpected or invalid content"

This usually means the block's HTML was hand-edited or copied incorrectly. Click Attempt Block Recovery when prompted - this will restore the block from its saved attributes.

The block renders but looks completely unstyled

WP Career Board enqueues its CSS only on pages that contain its blocks. If you are embedding a shortcode or pasting raw HTML outside a block, styles won't load. Use the block editor and insert the correct block instead.


Performance

The jobs page is slow

  • Enable object caching on your server (Redis or Memcached) - WP Career Board caches job queries.
  • If using a page caching plugin, configure it to exclude the Candidate Dashboard and Employer Dashboard pages (they are user-specific and must not be served from cache).
  • The job search uses a live REST API call on every keystroke (with debounce). If the REST API is slow, check for slow database queries using Query Monitor.

Still Stuck?

If none of the above resolves your issue:

  1. Enable WP_DEBUG and WP_DEBUG_LOG in wp-config.php and check wp-content/debug.log for PHP errors.
  2. Deactivate all plugins except WP Career Board to rule out conflicts, then reactivate one by one.
  3. Open a support ticket at wbcomdesigns.com/support with your WordPress version, PHP version, active theme, and a description of what you tried.

Jobs RSS Feed

The plugin exposes a rich RSS feed at /jobs/feed/ containing every published job with full metadata. Wire it up to RSS readers, IFTTT, Zapier, partner aggregators, or your own automation.

Where to find it

https://your-site.com/jobs/feed/

The URL respects whatever post-type slug you've configured (defaults to jobs). If you've changed the slug, the feed URL changes with it.

Item schema

Each <item> in the feed contains:

Field Source
<title> Job title
<link> Job permalink
<description> Full job description (HTML stripped to plain text + 500-char excerpt)
<pubDate> Job publish date
<guid> Job permalink (stable, isPermaLink="true")
<wcb:company> Company name
<wcb:salary_min> Minimum salary (numeric, no formatting)
<wcb:salary_max> Maximum salary
<wcb:salary_currency> ISO 4217 code (USD, EUR, GBP, etc.)
<wcb:salary_period> yearly / monthly / hourly
<wcb:location> Job location string
<wcb:job_type> Full-time / Part-time / Contract / etc.
<wcb:experience> Entry / Mid / Senior / Lead / Executive
<wcb:category> Category slug + display name
<wcb:tags> Comma-separated tag slugs
<wcb:deadline> Application deadline (ISO 8601) - if set
<wcb:apply_url> Direct apply URL (uses external URL if employer set one, otherwise the job permalink)
<wcb:remote> 1 or 0

The wcb: namespace is declared on the <rss> root so RSS readers that support custom namespaces (most modern ones) can surface these fields.

Filtering the feed

Feed URL accepts query string parameters that mirror the REST API:

/jobs/feed/?board_id=42                 # only board 42's jobs
/jobs/feed/?category=engineering        # category slug
/jobs/feed/?type=full-time              # job type slug
/jobs/feed/?remote=1                    # remote-only
/jobs/feed/?salary_min=80000            # $80k+ minimum

Combine multiple filters with &.

Use cases

  • Cross-post to a Slack channel via Zapier or RSS-to-Slack integration when new jobs are published.
  • Job aggregator listings - many aggregators accept RSS as their ingestion format (Indeed, ZipRecruiter, Google Jobs feeds).
  • Email digest - feed an RSS-to-email tool (Mailchimp, ConvertKit) to send weekly digests.
  • Static site builder - feed Astro / Next.js / Hugo with the feed during build to render a careers page on a marketing site.
  • IFTTT / make.com - trigger downstream automations on new jobs.

Cache + performance

The feed respects WordPress's standard feed caching. WP_DEBUG-disabled production sites cache the feed output for ~5 minutes by default. Tools like WP Super Cache and W3 Total Cache also cache feeds.

If you need a real-time feed for a specific integration, hit the REST endpoint directly:

GET /wp-json/wcb/v1/jobs?per_page=20&orderby=date&order=DESC

The REST API returns JSON with the same data but without RSS-format overhead.

Multilingual: WPML / Polylang

WP Career Board ships with WPML and Polylang configuration files out of the box, so multilingual sites can translate job board CPTs, taxonomies, and key strings without manual setup.

What's translatable

Object WPML Polylang
wcb_job (Jobs)
wcb_application (Applications) ✅ - but typically copied per-language to keep the original applicant context
wcb_resume (Resumes)
wcb_company (Companies)
wcb_board (Boards)
wcb_credit_package
Taxonomies (wcb_category, wcb_job_type, wcb_location, wcb_experience, wcb_tag)
Plugin admin strings ✅ via .po / .mo ✅ via .po / .mo
Block attributes (e.g. heading text on Job Listings block)

WPML setup

WP Career Board ships a wpml-config.xml at the plugin root. Activating WPML on a site that already has the plugin active picks up the config automatically.

To verify:

  1. WPML → Translation Management - Jobs, Applications, Resumes, Companies, and Boards should all appear in the post-type selector.
  2. WPML → Settings → Custom Posts - each WCB post type should be set to "Translatable - only show translated items".
  3. WPML → Taxonomy Translation - all 5 WCB taxonomies should be listed and translatable.

Polylang setup

Polylang reads the same wpml-config.xml as WPML (the format is shared between the two plugins for cross-compatibility).

To verify:

  1. Languages → Settings → Custom post types and Taxonomies - tick the WCB post types and taxonomies under "Activate languages and translations management for".
  2. Save.

The plugin then exposes the standard Polylang language switcher in the admin list tables and front-end blocks.

Front-end behavior

Job listings, the Find Jobs page, and the Apply form all respect the current request language:

  • A user browsing the site in fr_FR sees only French jobs in the listings (or all jobs if "Display all languages" is on in WPML / Polylang settings).
  • The Apply form labels, validation messages, and confirmation message render in the request language.
  • REST API endpoints (GET /wcb/v1/jobs) accept a lang query parameter to filter by language.

Translating plugin strings

The plugin's source .pot file lives at languages/wp-career-board.pot. Translators can:

  • Drop a translated .po / .mo pair under wp-content/languages/plugins/ (override location).
  • OR use Loco Translate, WPML's String Translation, or Polylang's String Translation interface to translate inline.

Currency & locale formatting

Salary formatting respects the site locale:

  • en_US$60,000-$120,000/yr
  • fr_FR60 000 €-120 000 €/an
  • de_DE60.000 €-120.000 €/Jahr

Date formatting (job posted dates, application dates) follows WordPress's date_format + time_format site settings, localized per language.

Known limitations

  • Custom field schema - fields registered via wcb_job_form_fields are translatable using WPML's String Translation, but Polylang requires manual translation entries.
  • Email templates - the email body is sent in the recipient's user-locale (set on each user's profile). Sites without per-user locales fall back to the site default.
  • AI features (Pro) - embeddings + AI matching work language-agnostically, but the UI strings respect the request language.

REST Meta Filters

The GET /wcb/v1/jobs REST endpoint accepts postmeta filters via ?meta_<key>=<value>. The Job Listings block exposes the same surface through its metaFilter attribute.

Default-allow rule (1.2.0+)

Any meta key in the _wcb_* namespace is allowed by default. The plugin owns that prefix, so there is no probe risk for fields like _wcb_visa_sponsorship, _wcb_seniority_score, _wcb_department, etc. Drop the block in the editor or hit the REST endpoint directly without any PHP setup:

GET /wp-json/wcb/v1/jobs?meta__wcb_visa_sponsorship=1
GET /wp-json/wcb/v1/jobs?meta__wcb_department=engineering
[wcb_job_listings metaFilter="_wcb_visa_sponsorship:1"]
[wcb_job_listings metaFilter="_wcb_department:engineering"]

Custom (non-WCB) meta still needs opt-in

Custom or third-party meta keys - anything that doesn't start with _wcb_ - still need to be added to the wcb_jobs_allowed_meta_filters filter before they can be queried. This prevents anonymous probes against arbitrary site-internal postmeta (e.g. a private membership flag set by another plugin):

add_filter( 'wcb_jobs_allowed_meta_filters', function( $keys ) {
    $keys[] = 'partner_company_id';       // not _wcb_*, must opt in
    $keys[] = 'crm_sync_state';           // same
    return $keys;
} );

Then anonymous callers can hit:

GET /wp-json/wcb/v1/jobs?meta_partner_company_id=42

Why this split?

Without any allowlist, any caller could query against any postmeta - including private fields the plugin or other plugins use for internal bookkeeping (e.g. _wcb_employer_banned, _wcb_pending_review_token, or a membership plugin's _member_level field). The pre-1.2.0 behavior required allowlisting every key, which made the common case (filter jobs by a _wcb_* field set by the plugin itself) require PHP. The 1.2.0 split allows the namespace WCB owns while still gating foreign meta.

Block + shortcode integration

The Job Listings block exposes a metaFilter attribute on every shipped surface - Gutenberg inserter, shortcode wrapper, and page-builder embeds:

metaFilter attribute in the block inspector

If you reference a key that's NOT in the _wcb_* namespace and NOT on the explicit allowlist, the block falls back to showing all jobs (no error, but the filter is silently ignored) and a _doing_it_wrong notice fires in WP_DEBUG mode telling you which filter to register.

Common patterns

Boolean meta

$keys[] = '_wcb_visa_sponsorship';
$keys[] = '_wcb_relocation_offered';
$keys[] = '_wcb_remote_friendly';

Then on the front end:

?meta__wcb_visa_sponsorship=1
?meta__wcb_relocation_offered=1

Range meta (numeric)

For range queries, register both bounds:

$keys[] = '_wcb_team_size';

Then use comparison operators in the URL (the endpoint accepts _min / _max suffix conventions for any allowlisted numeric key):

?meta__wcb_team_size_min=10
?meta__wcb_team_size_max=50

Slug-list meta

For meta storing serialized arrays of slugs:

$keys[] = '_wcb_skills_required';
?meta__wcb_skills_required=python,docker

The endpoint matches if any of the comma-separated values appear in the meta array.

Performance notes

  • All allowlisted meta filters are added to the WP_Query meta_query array. WordPress core handles indexing.
  • For high-traffic boards, add an index on the relevant rows in wp_postmeta:
    ALTER TABLE wp_postmeta ADD INDEX wcb_meta_visa (meta_key, meta_value(20));
    
  • The REST endpoint caches per-user-locale + per-query-hash for 5 minutes by default; use wcb_cache_ttl filter to change.

See also

Custom Fields (declarative filters)

Add custom fields to any plugin form - Job Form, Company Form, Candidate Profile, Application Form - with one add_filter call. The filter takes a single field-group schema; the plugin handles rendering, validation, persistence, REST exposure, and admin display.

The four filters

Filter Form
wcb_job_form_fields Post a Job (multi-step + single-page forms)
wcb_company_form_fields Company profile editor
wcb_candidate_form_fields Candidate profile editor
wcb_application_form_fields_groups Apply to a job

All four use the same field-group schema - once you've learned one, you've learned all four.

Schema

A field group looks like this:

[
    'group_id'    => 'employer_screening',
    'group_label' => __( 'Screening Questions', 'wp-career-board' ),
    'fields'      => [
        [
            'key'         => 'years_experience',
            'label'       => __( 'Years of relevant experience', 'wp-career-board' ),
            'type'        => 'number',
            'required'    => true,
            'min'         => 0,
            'max'         => 60,
        ],
        [
            'key'         => 'visa_status',
            'label'       => __( 'Current visa status', 'wp-career-board' ),
            'type'        => 'select',
            'required'    => true,
            'options'     => [
                'us-citizen'    => 'US Citizen',
                'green-card'    => 'Green Card',
                'h1b'           => 'H-1B',
                'opt'           => 'OPT',
                'needs-sponsor' => 'Needs sponsorship',
            ],
        ],
        [
            'key'         => 'portfolio_url',
            'label'       => __( 'Portfolio URL', 'wp-career-board' ),
            'type'        => 'url',
            'required'    => false,
            'placeholder' => 'https://',
        ],
    ],
]

Field types

Type Renders Stored as
text Single-line input string
textarea Multi-line textarea string
email Email input + validation string
url URL input + validation string
number Numeric input with min/max int / float
select Dropdown string (option key)
radio Radio button group string (option key)
checkbox Single boolean checkbox '1' / ''
multi-checkbox Multiple checkboxes array of option keys
date Date picker YYYY-MM-DD string

Example: Add a "Portfolio URL" field to the candidate profile

add_filter( 'wcb_candidate_form_fields', function( $groups ) {
    $groups[] = [
        'group_id'    => 'links',
        'group_label' => __( 'Online presence', 'wp-career-board' ),
        'fields'      => [
            [
                'key'      => 'portfolio_url',
                'label'    => __( 'Portfolio URL', 'wp-career-board' ),
                'type'     => 'url',
                'required' => false,
            ],
            [
                'key'      => 'github_url',
                'label'    => __( 'GitHub profile URL', 'wp-career-board' ),
                'type'     => 'url',
                'required' => false,
            ],
        ],
    ];
    return $groups;
} );

After this filter is in place:

  • The candidate profile editor renders both fields.
  • The fields validate on save (URL format).
  • Values persist as user meta _wcb_candidate_field_portfolio_url and _wcb_candidate_field_github_url.
  • They appear in the candidate's REST response on GET /wcb/v1/candidates/{id}.

Example: Add a screening question to the application form

add_filter( 'wcb_application_form_fields_groups', function( $groups, $job_id ) {
    $groups[] = [
        'group_id'    => 'screening',
        'group_label' => __( 'Quick screen', 'wp-career-board' ),
        'fields'      => [
            [
                'key'      => 'years_relevant',
                'label'    => __( 'Years of relevant experience', 'wp-career-board' ),
                'type'     => 'number',
                'required' => true,
            ],
            [
                'key'      => 'salary_expectation',
                'label'    => __( 'Salary expectation (USD/yr)', 'wp-career-board' ),
                'type'     => 'number',
                'required' => false,
            ],
        ],
    ];
    return $groups;
}, 10, 2 );

This adds the screening group to every job's apply form. To scope to specific jobs, branch on $job_id inside the callback.

Per-job custom fields (Pro field builder)

The above filter applies globally. For per-job configuration without writing PHP, install Pro and use the Field Builder admin page - the builder writes the same data structure to the wcb_field_groups / wcb_field_definitions Pro tables and contributes to the same filters automatically.

Where the data appears

Custom field values appear:

  • In the admin Edit Application screen - under a "Custom fields" section per group.
  • In the bulk CSV export - one column per field key.
  • In the REST API - under the custom_fields key of the job / company / candidate / application response.
  • In templates - via the Icon::svg() style helpers and direct postmeta reads (get_post_meta($id, '_wcb_application_field_<key>', true)).

Persistence keys

Per surface:

Filter Stored where Meta key prefix
wcb_job_form_fields wp_postmeta (job) _wcb_job_field_<key>
wcb_company_form_fields wp_postmeta (company) _wcb_company_field_<key>
wcb_candidate_form_fields wp_usermeta (candidate) _wcb_candidate_field_<key>
wcb_application_form_fields_groups wp_postmeta (application) _wcb_application_field_<key>

A bundle of all field values also lives at the corresponding _wcb_*_fields_bundle key for one-shot reads.

Application Editor (re-built)

The Edit Application admin screen has been rebuilt around the applicant - replacing the previously empty native post-edit screen with a full review surface that has everything an employer needs in one place.

What's on the screen

Section What it shows
Applicant card Avatar, name, email, phone (if collected), location
Cover letter Full text, formatted
Resume preview Inline preview with Open + Download buttons
Status changer Submitted / Reviewing / Shortlisted / Rejected - instant save on change
Quick action buttons Shortlist / Mark Hired / Reject / Message
Status history Full audit trail - who changed status, when, from / to
Custom fields Whatever the site has registered via wcb_application_form_fields_groups

Where to find it

wp-admin → Career Board → Applications → click any application row

Or via direct URL: /wp-admin/post.php?post=<id>&action=edit (the plugin redirects native post-edit URLs to the new admin screen).

Quick actions

The four quick-action buttons (Shortlist / Mark Hired / Reject / Message) each fire the corresponding workflow:

  • Shortlist - sets status to shortlisted, sends the configured shortlist email to the applicant, posts a status-change history entry.
  • Mark Hired - sets status to hired, sends hire email, posts to BuddyPress activity stream (Pro), and triggers the candidate- side "congratulations" notification.
  • Reject - sets status to rejected, sends rejection email (templated, customizable), records history.
  • Message - opens an inline reply composer that uses the same wp_mail() chokepoint as automated emails. Uses the configured email-template merge tags ({{candidate_name}}, {{job_title}}, etc.).

Status history

Every status change writes a row to the application's status history:

  • Who made the change (user ID + display name)
  • When (timestamp)
  • From → To (status slugs)
  • Optional note (employer can add a note when changing status)

The history shows in reverse-chronological order on the application screen. It's also exposed as application.status_history on the REST endpoint for ATS integrations.

Modular widget system

Every component on the application screen - applicant card, cover letter, resume preview, status changer, action buttons, history - also works as a standalone shortcode you can embed anywhere:

[wcb_widget id="applicant_card" application_id="987"]
[wcb_widget id="resume_preview" application_id="987"]
[wcb_widget id="status_history" application_id="987"]
[wcb_widget id="status_changer" application_id="987"]
[wcb_widget id="action_buttons" application_id="987"]

This is useful for:

  • Partner profile pages - embed the applicant card on a partner's candidate-facing page
  • Custom admin dashboards - composite widgets into a different arrangement using a dashboard plugin
  • Email templates - generate a snapshot of the applicant card to attach to a forwarded email

The widget shortcodes respect the same capabilities as the admin screen - embedding [wcb_widget id="status_changer" application_id="987"] on a public page only renders the changer for users with wcb_manage_applications ability.

Bulk operations

The list table (one level up from the editor) supports bulk operations:

  • Bulk export to CSV - see Bulk CSV Export.
  • Bulk status change - set multiple applications to the same status in one action.
  • Bulk delete - same as native WP bulk delete on CPTs.

Permissions

Capability What it grants
wcb_manage_applications Read the editor screen, run quick actions, change status
edit_post (per-application) Standard WP per-post edit gate; required to modify applicant data
wcb_employer role Site default - gets wcb_manage_applications for applications belonging to their own jobs only
manage_options Site admin override - can edit any application

See also

Capabilities & Roles

WP Career Board ships with 3 custom roles and 12 custom capabilities. Site administrators have every Career Board cap by default; the custom roles get a focused subset. Use this page to decide what to grant team members.

The custom roles

Role Slug Purpose
Candidate wcb_candidate Anyone who applies to jobs and manages a resume
Board Moderator wcb_board_moderator Reviews pending jobs and approves/rejects
Banned Employer wcb_employer_banned Suspended account - can still log in but cannot post

Note: "Employer" is not a separate role in Career Board. Anyone who has the wcb_post_jobs capability is an employer for our purposes. Many sites assign that cap to the Editor role, or create their own custom role and add it.

The 12 capabilities

Capability What it lets the user do
wcb_post_jobs Post a job, edit / republish own jobs
wcb_apply_jobs Apply to jobs, submit a resume on the apply form
wcb_manage_company Edit the company profile they're attached to
wcb_view_applications See incoming applications for their job posts
wcb_manage_resume Create / edit / publish a resume (Candidate flow)
wcb_bookmark_jobs Save jobs to "My Saved Jobs"
wcb_withdraw_application Withdraw an application after submitting
wcb_moderate_jobs Approve or reject pending jobs
wcb_view_analytics See the analytics dashboard (Pro)
wcb_manage_settings Configure Career Board settings, emails, integrations
wcb_access_employer_dashboard See the Employer Dashboard page
wcb_access_candidate_dashboard See the Candidate Dashboard page

Default capability map

Role Capabilities granted
Administrator All 12
Editor None by default - usually granted wcb_post_jobs + wcb_view_applications + wcb_access_employer_dashboard for editorial sites
Author None by default
Candidate (wcb_candidate) read, wcb_apply_jobs, wcb_manage_resume, wcb_bookmark_jobs, wcb_access_candidate_dashboard, wcb_withdraw_application
Board Moderator (wcb_board_moderator) read, wcb_moderate_jobs
Banned Employer (wcb_employer_banned) None of the Career Board caps. Still has read so they can log in and see the suspension message.

Granting capabilities to other roles

The easiest path is via a role manager plugin (User Role Editor, Members, etc.):

  1. Install your preferred role manager.
  2. Edit the target role.
  3. Tick the Career Board capabilities you want to grant.
  4. Save.

For "Editor as Employer" - the most common scenario:

Grant the Editor role:

  • wcb_post_jobs
  • wcb_view_applications
  • wcb_access_employer_dashboard
  • wcb_manage_company (so they can edit their company profile)

That gives editorial staff the ability to post and review jobs without the broader site-admin access.

Built-in registration

The plugin's registration flow creates accounts with these roles:

  • Employer registration (/employer-registration/) creates a user with the wcb_post_jobs cap added to whatever role you set in Settings → Registration → Default employer role. Default is "Editor."
  • Candidate registration (Candidate Dashboard → Register tab) creates a user with the wcb_candidate role.

You can override the default roles via the wcb_employer_default_role and wcb_candidate_default_role settings (Settings → Registration).

Banning an employer

Set the user's role to Banned Employer (wcb_employer_banned):

wp user set-role <login> wcb_employer_banned

Or via WP Admin → Users → edit → Role dropdown.

Effects:

  • They lose wcb_post_jobs - cannot create new jobs.
  • Existing published jobs stay live (use this carefully - if you want them down, change the job's status to pending or draft separately).
  • They can still log in, but the dashboard shows a suspension message instead of the post-job form.

To unban, set the role back to whatever they had before (typically Editor).

How the plugin actually checks permissions

Internally Career Board uses the WordPress Abilities API (wp_register_ability + wp_is_ability_granted) rather than raw current_user_can calls. Each capability above maps to a namespaced ability slug:

Ability slug Backing capability
wcb/post-jobs wcb_post_jobs
wcb/apply-jobs wcb_apply_jobs
wcb/manage-settings wcb_manage_settings
wcb/moderate-jobs wcb_moderate_jobs
wcb/manage-resume wcb_manage_resume
wcb/bookmark-jobs wcb_bookmark_jobs
wcb/withdraw-application wcb_withdraw_application
wcb/manage-company wcb_manage_company
wcb/view-applications wcb_view_applications
wcb/view-analytics wcb_view_analytics

You only need to grant the underlying capability - the Abilities layer reads it. Both forms work for current_user_can() checks in your own theme/plugin code, though wp_is_ability_granted() is the canonical call.

Adding your own role

If you want a custom role (e.g. "Premium Employer") with a different mix:

add_action( 'init', function () {
    add_role( 'wcb_premium_employer', __( 'Premium Employer', 'my-addon' ), array(
        'read'                          => true,
        'wcb_post_jobs'                 => true,
        'wcb_view_applications'         => true,
        'wcb_manage_company'            => true,
        'wcb_access_employer_dashboard' => true,
        'wcb_view_analytics'            => true,  // Pro-only, no-op without Pro
    ));
});

To remove the role on uninstall, call remove_role() in the same file (or in your plugin's uninstall hook).

Troubleshooting permissions

"You don't have permission to do this" when an employer tries to post a job.

Check the employer's user role has wcb_post_jobs. The fastest check:

wp user get <login> --field=roles
wp user list-caps <login> | grep wcb_

"You don't have permission" when admin tries to change settings.

The setting check is wcb_manage_settings, which Administrator has by default. If you're an Editor temporarily acting as admin, you don't have it.

Candidate registered but can't apply.

Their role might have been overridden by another plugin's registration flow. Check wp user get <login> --field=roles - it should be wcb_candidate. If it's subscriber or customer, either change the role manually or add wcb_apply_jobs to whatever role they got.

Company Profile Sidebar

WP Career Board 1.1.1 adds a right-column sidebar to every company single page (/companies/<slug>/). Site admins customise it like any other WordPress widget area; if left empty, three useful default blocks render automatically so the column is never wasted.

What it looks like

On desktop (>1024px) the company profile renders in a two-column grid:

  • Main column (left): the existing About, Company Details, and Open Positions sections.
  • Sidebar column (right, 320px): the widget area named "Company Profile Sidebar".

On mobile (≤1024px) the sidebar stacks below the main content.

Default behaviour (no admin setup required)

When the Company Profile Sidebar widget area is empty, the page auto-renders three Career Board blocks:

Block What it shows
Similar Companies (wcb/similar-companies-card) Top 5 companies in the same industry as the company being viewed.
Recent Jobs (wcb/recent-jobs) The 5 most recently published jobs across the board.
Job Alerts CTA (wcb/job-alert-card) A small card linking candidates to the alerts signup flow.

You don't have to do anything to get these. They're the soft fallback.

Adding your own widgets

Override the defaults by adding any blocks to the widget area:

  1. Go to Appearance → Widgets.
  2. Find the Company Profile Sidebar area.
  3. Drop in any block: a Career Board block, a built-in WordPress block (Image, Heading, Custom HTML, etc.), or any third-party block.
  4. Save.

As soon as the area contains one or more widgets, the defaults are replaced. If you later remove all widgets, the defaults come back automatically.

Which Career Board blocks fit well in the sidebar

The Career Board sidebar blocks (all 320px-friendly):

  • Similar Companies (wcb/similar-companies-card) - same-industry companies, with optional Company ID for use on non-company pages.
  • Recent Jobs (wcb/recent-jobs) - latest published jobs.
  • Featured Jobs (wcb/featured-jobs) - featured listings grid.
  • Job Alerts CTA (wcb/job-alert-card) - signup nudge card.
  • Job Stats (wcb/job-stats) - aggregate counts.

All ship as shortcodes too if you're using a page builder:

  • [wcb_similar_companies count="5"]
  • [wcb_recent_jobs count="5"]
  • [wcb_featured_jobs perPage="3"]
  • [wcb_job_alert_card]
  • [wcb_job_stats]

Suppression of the theme's own sidebar

On company singles, Career Board hides the active theme's primary sidebar (#secondary, .widget-area, aside.sidebar, etc.) and forces the parent content column to full width. This is intentional: themes often pre-populate their sidebars with Archives, Categories, Recent Posts widgets that don't make sense on a company page. The company-profile block takes over that space and renders its own sidebar instead.

If you want the theme's primary sidebar to remain visible on company pages too, you can filter it back in with a tiny mu-plugin:

add_action(
    'wp_enqueue_scripts',
    function () {
        if ( is_singular( 'wcb_company' ) ) {
            wp_add_inline_style(
                'wp-career-board-company-profile-style',
                '.wcb-company-page #secondary { display: block !important; }'
            );
        }
    },
    20
);

This is rarely needed - the in-block sidebar is the cleaner UX - but it's available as an override.

Standalone use on other pages

The two new blocks also work outside the company-profile context:

  • wcb/similar-companies-card has a Company ID attribute in the editor inspector. Drop the block on any page and set the ID to anchor it to a specific company. Leave blank when used inside the Company Profile Sidebar (it auto-resolves there).

  • wcb/job-alert-card has fully editable title, body, button text, and URL. Use it on landing pages, footer columns, or wherever you want a "Get Job Alerts" CTA.

Theme compatibility

Tested across:

  • BuddyX Pro (the company-page CSS overrides BuddyX's grid-template-columns: 978px 260px to single-column on company singles so our content fills the freed space).
  • Reign.
  • Astra, Kadence, GeneratePress (collapse via .ast-container, .container-grid selector overrides).
  • Twenty Twenty-Three / Four / Five (block themes work out of the box).

If you find a theme where the layout looks wrong, file an issue with the active theme name plus a screenshot - the per-theme CSS shim is a one-line addition.

Where to go next

AI Features

AI-assisted job description writing, candidate screening, and applicant matching.

AI Features Overview

WP Career Board can use AI to improve three parts of the hiring flow: job description writing, natural-language job search, and candidate-to-job matching. All AI features ship in the Pro plugin; the Free plugin defines the gate filter so an add-on or Pro can wire AI in without changes elsewhere.

This page summarises what's actually in the 1.1.1 release, what's gated behind the AI provider being configured, and what's queued for a later release. If you're on Free, treat this as a feature preview: the flows here are what you get when you upgrade.

What ships today (1.1.1)

Feature Surface Who uses it
Job embeddings Background: every new job is embedded on wcb_job_created into the wcb_ai_vectors table. System
AI Chat Search block wcb/ai-chat-search block. Candidate types a natural-language query; closest-matched jobs come back via the /wcb/v1/ai/match REST endpoint. Candidates
AI Job Description Writer "Generate with AI" button on the post-a-job form, gated behind wcb_ai_description_enabled. Sends title + company type + location to the provider. Employers
Candidate-to-job match data (REST) GET /wcb/v1/candidates/{id}/matches returns top-N matches for a candidate. No built-in UI surface in 1.1.1 - consumed by add-ons or custom templates. Add-on developers
Application ranking data (REST) GET /wcb/v1/ai/ranked-applications/{job_id} returns each application's AI fit score (0-100). No built-in admin column UI in 1.1.1. Add-on developers

In Free, all five paths are gated. The Chat Search block returns an empty list, the description button is hidden, the match / rank REST routes aren't registered. No broken UI surfaces in Free.

What's queued for a later release

Listed honestly so expectations are calibrated:

  • Resume parsing - the wcbp_candidate_resume_data filter exists for an add-on to supply parsed data, but Pro does not ship a parser in 1.1.1.
  • AI fit-score column on the applications admin screen - data is available via REST, but the column UI isn't registered.
  • Sort by AI fit score - depends on the column above.
  • Per-application refresh button - manual recomputation is via AiModule::rank_applications() from a custom integration; no built-in button.
  • "Test connection" + "Reindex all jobs" buttons in AI Settings - validation happens only on real calls; existing jobs (before AI was enabled) don't auto-backfill embeddings.
  • WP-CLI wp wcb ai * commands - not registered.
  • AI lifecycle action hooks (e.g. wcbp_ai_job_embedded, wcbp_ai_application_scored) - not fired in 1.1.1; instrument from your add-on by wrapping the public AiModule methods.
  • Semantic match for Pro Job Alerts - alerts use keyword match in 1.1.1.

If any of these is a blocker for your use case, file on the support board so it can be prioritised for the next release.

Free vs Pro at a glance

Free Pro
Job posting form Full editor Full editor + AI description writer button
Candidate dashboard Resume upload, manual profile fill Same (Pro does NOT auto-parse in 1.1.1)
Search bar Keyword search, taxonomy filters Keyword + filters + AI Chat Search block
Applications screen List, status filter, manual review Same UI as Free in 1.1.1; AI ranking data available via REST for custom UI
AI Settings tab Hidden Visible under WP Admin → Career Board → Settings → AI Settings
Database Standard tables only Adds wcb_ai_vectors for embeddings

When AI is worth turning on

Turn it on if:

  • Your board has more than ~30 active jobs and candidates struggle to find the right one with keyword search alone.
  • You want the description-writer assist to speed up job posting.
  • You're building an add-on or custom UI that wants AI match / rank data from the REST endpoints.

Skip it if:

  • You're under 20 active jobs and a handful of applications a week - the description writer might still help, but match / rank don't move the needle yet.
  • You can't share job / candidate text with a third-party LLM provider for privacy / compliance reasons. (Use Ollama locally; see 02-setup-and-providers.md.)
  • You expect resume parsing, AI-ranked applications visible in the admin, or AI-powered alerts in 1.1.1 - those aren't shipping yet.

How it works under the hood

When AI is enabled and a provider is configured:

  1. On job publish: Pro hooks wcb_job_created and calls AiModule::generate_job_embedding(). The job title + content are embedded by the configured provider and stored as a binary-packed float vector in wcb_ai_vectors.
  2. On AI Chat Search: the candidate's query is embedded the same way, then cosine-similarity-compared against every stored job vector. Top 10 matches are returned via POST /wcb/v1/ai/match.
  3. On description writer: the form sends title + company type + location to POST /wcb/v1/jobs/ai-description. The provider returns a description; the editor inserts it.
  4. On candidate matching (REST): the candidate's resume data (provided by an add-on via wcbp_candidate_resume_data) is embedded and matched against job vectors.
  5. On application ranking (REST): each application's candidate resume data is sent to the completions provider with a 0-100 scoring prompt. Returns [{application_id, score, reason}].

All paths go through the same AiModule and the configured provider (OpenAI / Anthropic Claude / Ollama). One provider config drives all features - no per-feature API key.

What gets sent to the AI provider

The privacy-relevant breakdown:

Feature What's sent
Job embedding (on publish) The job title and description as plain text.
AI Chat Search The candidate's typed query string.
AI Description Writer The job title, company type, and location.
Candidate match / rank (REST) The candidate's resume data array, as supplied to wcbp_candidate_resume_data.

For privacy-sensitive deployments, run Ollama locally - see 02-setup-and-providers.md. Nothing leaves your server.

What it doesn't do (1.1.1)

  • No auto-rejection. Application ranking returns scores; nothing acts on them automatically. Every decision still lands with the employer.
  • No auto-matching emails. Pro Job Alerts (when active) use keyword match in 1.1.1, not AI semantic match.
  • No content generation outside the writer. AI does not auto-fill candidate bios, company "about us" sections, etc.
  • No data sold or shared. All API calls are between your site and the configured provider directly - Wbcom never sees or proxies the data.

Where to go next

Setup & Providers

Pro feature. The AI Settings tab only appears when WP Career Board Pro is installed, active, and licensed. On Free this page applies once you upgrade.

WP Career Board Pro supports three AI providers. Pick one based on your hosting setup, privacy needs, and budget. You can switch at any time.

Provider comparison

Provider Embeddings model Completions model Where it runs Cost ballpark
OpenAI text-embedding-3-small (1536-dim) gpt-4o-mini OpenAI servers (USA) $0.02 per 1M embedding tokens, $0.15 / 1M input + $0.60 / 1M output for completions
Anthropic Claude Not supported claude-haiku-4-5 Anthropic servers (USA) $0.80 / 1M input + $4.00 / 1M output for completions. Requires OpenAI or Ollama for embeddings.
Ollama nomic-embed-text (768-dim) llama3 (8B by default) Your server / your hardware Free (your compute)

Recommended default: OpenAI. Best balance of quality, cost, and zero setup. Use Claude when you specifically want better description-writer copy. Use Ollama when content must not leave your server.

Cost estimation (OpenAI)

Rough back-of-envelope for a typical mid-size board:

Activity Tokens per event Events per month Monthly cost
Job publish (embedding) ~300 in 100 new jobs ~$0.001
AI Chat Search query ~50 in 5,000 searches ~$0.0005
Application Ranking (REST) ~2500 in / ~150 out 800 scored ~$1.40
Job Description Writer ~500 in / ~500 out 100 generations ~$0.31
Total per month ≈ $1.70

For a large board (10× the above), expect $10-$20 / month. Set a monthly cap on your OpenAI billing dashboard - that's the surest way to catch a runaway loop. Claude is roughly 5-10× the per-token cost of OpenAI. Ollama is free but uses your CPU / GPU.

Step 1 - pick a provider

  1. Go to WP Admin → Career Board → Settings → AI Settings.
  2. Provider dropdown - choose OpenAI, Anthropic Claude, Ollama, or Disabled (none).

If you can't see the AI Settings tab, check that Pro is active and the license is valid (Settings → License).

Step 2 - enter your key (or base URL)

OpenAI

  1. Sign in at platform.openai.com.
  2. Billing → Payment methods - add a card. OpenAI requires a payment method even for low-volume use.
  3. API keys → Create new secret key. Copy the sk-... value immediately (you can't view it again - only its prefix).
  4. Paste into the API Key field on the AI Settings tab.
  5. Set a Monthly budget on the OpenAI dashboard. Recommendation: $20 / month for a starting board, and raise if you actually hit it.

Anthropic Claude

  1. Sign in at console.anthropic.com.
  2. Add a payment method.
  3. API keys → Create key. Copy the sk-ant-... value.
  4. Paste into the API Key field.
  5. Important: Claude doesn't do embeddings. AI Chat Search and candidate matching need a secondary embeddings provider. Easiest path is to also configure OpenAI - the embeddings half uses OpenAI while completions go through Claude.

Ollama (self-hosted)

  1. Install on your server: curl -fsSL https://ollama.com/install.sh | sh
  2. Pull the required models:
    ollama pull nomic-embed-text
    ollama pull llama3
    
    On a 4 GB VPS this takes a few minutes and uses about 5 GB of disk for both models.
  3. Confirm Ollama is reachable: curl http://localhost:11434/api/tags should return a JSON list including both models.
  4. In AI Settings, set the Base URL to http://localhost:11434 (or wherever Ollama is bound). No API key is needed.
  5. Server sizing: completions on llama3 require ~6 GB RAM and run slowly on CPU-only servers. For decent latency, run on a host with a GPU or use a smaller quantised variant (llama3:8b-instruct-q4_K_M).

Step 3 - save

Click Save AI Settings. Configuration is stored in three options: wcbp_ai_provider, wcbp_ai_api_key, wcbp_ai_base_url.

There is no separate "test connection" button in 1.1.1 - configuration is validated the first time a real AI call happens. To verify your setup is correct, open the post-a-job form (with the description-writer button enabled) and click Generate with AI - a successful generation confirms the provider + key are working.

Backfilling embeddings for existing jobs

Embeddings are generated only at wcb_job_created time in 1.1.1. If you turn on AI for the first time on a board with existing published jobs, those jobs have no embeddings - they won't appear in AI Chat Search results.

In 1.1.1, there is no built-in reindex button. To backfill, the options are:

Option A - re-save each job (any change saves a new vector). Manual; works for small boards.

Option B - one-off WP-CLI snippet:

wp eval '
$jobs = get_posts( array(
    "post_type"      => "wcb_job",
    "post_status"    => "publish",
    "posts_per_page" => -1,
    "fields"         => "ids",
));
$ai = new \WCB\Pro\Modules\Ai\AiModule();
foreach ( $jobs as $id ) {
    $ai->generate_job_embedding( $id );
    echo "Embedded $id\n";
}
'

Run this off-hours - each call is a provider API request. On OpenAI a 5000-job backfill takes a few minutes and costs ~$0.10.

A first-class reindex tool is queued for a later release.

Privacy and data flow per provider

Provider Where data goes Logged by provider Used for training?
OpenAI OpenAI's US servers via TLS Yes (kept 30 days for abuse monitoring) No, business-tier API is opted out of training by default
Anthropic Claude Anthropic's US servers via TLS Yes (kept up to 30 days) No, API data is not used for training
Ollama Stays on your server. Never leaves. Only if you log it yourself N/A

If you're under GDPR / CCPA / HIPAA constraints, use Ollama.

Switching providers

You can change providers at any time without losing data:

  • Existing job vectors are kept as-is. If you switch from OpenAI (1536-dim) to Ollama (768-dim) the dimensions don't match and cosine similarity returns 0 for every comparison - in practice AI Chat Search will then return no results until you backfill against the new provider (see "Backfilling embeddings" above).
  • Existing options (wcbp_ai_provider, wcbp_ai_api_key, wcbp_ai_base_url) are simply overwritten on save.

Disabling AI

Set Provider to None / Disabled and save. Effects:

  • AiModule::is_enabled() returns false.
  • AI Chat Search block silently returns an empty result set.
  • AI description writer button disappears (the wcb_ai_description_enabled filter resolves to false).
  • /ai/match, /candidates/{id}/matches, /ai/ranked-applications/{job_id}, and /jobs/ai-description return empty / 503 silently.
  • No new embeddings are generated.
  • Stored wcb_ai_vectors rows are kept (no destructive change). If you re-enable AI later, search resumes against the existing data.

To fully clean up: deactivate Pro, and on uninstall the AI tables go with it.

Common setup errors

The top three:

  • "Invalid API key" - wrong key or wrong provider selected. Re-copy from the provider dashboard. OpenAI keys start sk-, Anthropic keys start sk-ant-. Strip whitespace.
  • "Connection refused" (Ollama) - Ollama isn't running or the Base URL is wrong. ps aux | grep ollama to confirm; restart with systemctl restart ollama if needed.
  • "Quota exceeded" - your OpenAI or Anthropic monthly cap is hit. Raise the cap in the provider dashboard or wait for the next billing cycle.

See 06-troubleshooting.md for the full list.

Where to go next

AI Features for Candidates

Pro feature surface. These flows only activate when WP Career Board Pro is licensed and an AI provider is configured. On Free the keyword search and standard apply flow still work.

This page covers what candidates experience when AI is on in 1.1.1: the AI Chat Search bar. (Other AI capabilities you may have heard about - resume parsing, AI-powered alerts - are not shipping in 1.1.1; see 01-overview.md for the queued list.)

AI Chat Search

A natural-language search input that returns semantically relevant jobs - not just keyword matches.

Where it lives

The AI Chat Search block is something the site owner places on a page via the block editor. Most boards put it on the Find Jobs page, above the standard keyword search. If your board doesn't have it, ask the site admin to add the wcb/ai-chat-search block.

What candidates type

Anything natural-language. Examples that work well:

  • "Remote React job, US time zones, $100k+"
  • "Junior data analyst position, willing to relocate to Berlin"
  • "Marketing role at a B2B SaaS startup, 10-50 people, hybrid OK"
  • "Senior backend engineer, Rust or Go, no on-call"

What doesn't work as well:

  • One-word queries ("developer"). For a single word, the standard keyword search is faster and more predictable.
  • Queries that depend on context outside the listings ("the job from last week's newsletter"). The AI doesn't know about your other pages.

What candidates see

After they hit Enter:

  • A spinner for 1-3 seconds while the query is embedded and matched.
  • A list of jobs ranked by relevance, not by date. Each result is a job card.

The results render in-place via the Interactivity API - no page reload happens when they refine the query.

What it can't do

  • It won't enforce filters you didn't type. If a candidate types "any job," they get the top jobs by general relevance - not "any job filtered to Frontend, Berlin, full-time" unless they say so. The standard keyword filters still work as a fallback.
  • It doesn't store search history per candidate. Each query is embedded, matched, and forgotten on the backend.
  • It doesn't auto-recommend jobs by email. The board's standard Job Alerts system handles outreach; in 1.1.1 alerts use keyword match, not AI semantic match.
  • It's not real-time for very fresh jobs. Embeddings are generated synchronously at wcb_job_created, so the window between job publish and AI-searchable is typically under a second - but the embedding step depends on the provider being reachable.
  • It has a per-user rate limit: 30 AI calls per hour across all AI features. Heavy testers will hit a 429 and need to wait.

Tips for candidates

  • Be specific about non-negotiables. "Remote" surfaces; "no on-call" surfaces; "must use modern frameworks" is too vague.
  • Salary specifics help. "$80-100k" filters better than "good salary."
  • Include location AND remote preference. "Remote, US time zones, preferably East Coast" is a complete instruction.
  • If results feel off, refine - add one more constraint and resubmit.

What about resume parsing?

WP Career Board Pro 1.1.1 does not ship a resume-parser. The filter wcbp_candidate_resume_data exists so an add-on can supply parsed data into the AI matching / ranking flow, but Pro itself does not auto-fill profile fields from an uploaded resume.

In practice this means: candidates upload a resume the usual way and fill in their profile fields manually. The resume PDF gets attached to their applications as a file - employers can download and read it themselves.

When a resume parser ships in a later release, this page will be updated to document the flow.

What about AI in Job Alerts?

Pro Job Alerts run keyword + filter matching in 1.1.1. They do not use semantic / AI matching to widen results. If you set up an alert for "backend role," it surfaces jobs with "backend" in title or content - not jobs that say "server-side" but mean the same thing.

Semantic alert matching is queued for a later release.

What candidates get without Pro

Capability Free Pro 1.1.1
Browse all jobs Yes Yes
Keyword search + filters Yes Yes
Apply to jobs Yes Yes
Resume upload (attaches to applications) Yes Yes
Save jobs to bookmarks Yes Yes
Get email notifications Yes Yes
Natural-language AI search (AI Chat Search block) No Yes
Auto-parse resume into profile fields No No (queued)
Semantic match in job alerts No No (queued)
Top-N "jobs that match my profile" (via REST) No Yes (custom UI required)

Where to go next

AI Features for Employers

Pro feature surface. Employers on Free still get the full job-posting form, the full applications screen, and standard candidate review. The AI-assisted shortcuts below only appear when the site has Pro installed, licensed, and a provider configured.

This page covers what employers can do with AI in 1.1.1: the Job Description Writer during posting, and the AI ranking REST data for application triage.

AI Job Description Writer

A button on the post-a-job form that turns a few form fields into a job description draft. Employers always review and edit the output before publishing - nothing is auto-posted.

Where it lives

On the Post a Job form (Employer Dashboard or /post-a-job/), above the description editor:

  • A "Generate with AI" button (icon + label).
  • Visible only when:
    • Pro is active.
    • The wcb_ai_description_enabled filter resolves to true (Pro's AiModule::is_enabled() returns true when a provider + API key are configured).
    • The employer's role has wcb_post_jobs.

What gets sent to the AI

The writer endpoint (POST /wcb/v1/jobs/ai-description) accepts three fields in 1.1.1:

Field Source on the form
title Job title input
company_type Company type / industry input
location Job location input

These three are concatenated into a prompt asking the model to write a compelling job description with responsibilities and requirements, in plain text.

Note: 1.1.1 does NOT accept "key bullets" as input. If you want to inject role-specific bullets, edit the prompt template by filtering at the network level (e.g. a custom pre_http_request filter), or wait for a later release that adds a details field.

The flow

  1. Fill in the basics: job title, company, location, type.
  2. Click "Generate with AI." Spinner appears for 5-15 seconds (depends on provider - Claude is fastest, Ollama on CPU is slowest).
  3. A drafted description appears in the editor (replacing the editor contents).
  4. Edit it. Add company-specific details, tone, anything the AI missed. The output is a starting point.
  5. Submit the job as normal.

Tips for employers

  • A good title produces a better description. "Senior Backend Engineer (Rust + Tokio, billing service)" produces a more specific draft than "Software Engineer."
  • The output is generic by default. AI doesn't know your company. Plan to edit at least 30% of the draft for accuracy and tone.
  • Run it through your own eye before publishing. First-pass drafts often miss specific perks, your diversity statement, or HR legal language. Treat it like a junior intern's first draft.
  • Each generation costs API credits (~$0.003 on OpenAI's pricing per generation). Regenerating 5 times to get the tone right is still under $0.02.

Limits

  • Output is provider-determined - no per-request token cap in the plugin code.
  • Provider quality matters. Claude writes more naturally; OpenAI is a bit more formal; Ollama / llama3 is the weakest writer.
  • Rate limit: 30 AI calls per user per hour, shared across all AI features.
  • Returns plain text - the editor inserts whatever the provider returned, including any newline handling quirks.

AI Application Ranking (REST data only in 1.1.1)

Pro can score each application against the job description (0-100 + one-line reason) via REST. The score column is not rendered in the admin applications screen in 1.1.1 - the data is available, but a visible UI surface is queued for a later release.

How to fetch it

GET /wp-json/wcb/v1/ai/ranked-applications/{job_id}
Authorization: <session cookie, user with wcb_view_applications>

Returns:

[
  { "application_id": 41, "score": 87, "reason": "Strong React + TypeScript, mid-senior fit" },
  { "application_id": 42, "score": 65, "reason": "Generalist background; some required skills missing" },
  ...
]

Where this is useful today

Even without a built-in admin column, the data is useful in three common patterns:

  • Custom dashboard widget - hook dashboard_setup, fetch the endpoint for jobs the current user owns, display top 5 scored applicants per job.
  • CSV export augmentation - extend the applications CSV exporter (Pro feature) to add an AI Score column.
  • Slack / email digest - schedule a cron that fetches ranking and posts the top-3 per active role to a channel.

What the score means

  • 80-100 - strong match. Resume / profile genuinely aligns with the job. Worth interviewing.
  • 60-79 - partial match. Some required skills present, others missing. Read in full before deciding.
  • 40-59 - weak match. Limited overlap. Useful as triage signal, not as a filter.
  • Below 40 - minimal match. Most fields aren't aligned.

The score is one signal, not the answer. Other things to weigh - culture fit, location, salary expectations, soft skills - are not captured.

How it's computed

Pro sends the job title and the candidate's resume data (as supplied by an add-on hooking wcbp_candidate_resume_data) to the configured completions provider with a structured prompt asking for {score, reason}. The result is returned in the REST response; there's no built-in cache layer in 1.1.1 - every call re-scores.

Important caveats

  • No wcbp_candidate_resume_data filter implementation in Pro core. Without an add-on that hooks this filter and returns the candidate's data, the ranking endpoint returns empty strings to the AI - resulting in low scores across the board. Wire up the filter (or install an add-on that does) before relying on the rankings.
  • Don't auto-reject by score. AI bias is real; a low score on a great candidate (e.g. a career-changer) shouldn't short-circuit human review.
  • Recomputation is manual. No background refresh - call the endpoint when you want fresh scores.

Privacy considerations

This is the most data-heavy AI feature - every applicant's resume data is sent to the LLM provider on each scoring event. If your hiring policy doesn't allow that, switch to Ollama to keep everything on your server.

Combined workflow tip

Today's practical combo:

  1. Use Description Writer to draft a focused job posting (good descriptions produce better embeddings and downstream scoring).
  2. As applicants arrive, periodically query /ai/ranked-applications/{job_id} from a custom dashboard or tooling to prioritise who to review first.
  3. Wait for a future release for the in-admin column + sort.

What employers get without Pro

Capability Free Pro 1.1.1
Post a job Yes Yes
Manual job description editor Yes Yes
AI Description Writer button No Yes
Review applicants Yes Yes
Sort by date, status Yes Yes
AI fit-score column in admin No No (queued; REST data is available)
Application pipeline (Kanban) No Yes
Bulk actions on applications Yes Yes

Where to go next

AI Block & Developer Surface

Pro-only surface. The block, REST endpoints, and Pro filters below are registered by wp-career-board-pro. The Free plugin defines the gate filter wcb_ai_description_enabled so the description-writer button can be flipped on by Pro (or by an add-on that wants to ship its own AI driver).

This page documents the AI surface that actually ships in 1.1.1. If a feature isn't listed here, it isn't wired into the codebase yet, regardless of what marketing materials might say.

AI Chat Search block

The user-facing natural-language search bar.

Block reference

Property Value
Name wcb/ai-chat-search
Editor category Widgets
Render mode Server-side render (render.php) + Interactivity API frontend
Pro-only? Yes - registered by Pro only

Attributes (shipping in 1.1.1)

Only one attribute is exposed on the block today:

Attribute Type Default Description
placeholder string Describe your ideal job... Input placeholder text.

That's deliberate - the block is intentionally minimal in 1.1.1. Additional attributes (button label, max results, relevance bar, etc.) are tracked for a future release; if you need them today, copy blocks/ai-chat-search/render.php into a child plugin and customise.

How to add it to a page

  1. Open the page in the block editor.
  2. Add a new block; search for AI Chat Search.
  3. Optionally edit the placeholder text in the block sidebar.
  4. Save / publish.

Render contract

Server-side, the block:

  1. Reads the placeholder attribute and outputs an Interactivity API root.
  2. Loads view.js as a script module (no jQuery, no admin-ajax).
  3. On submit, the JS POSTs to /wp-json/wcb/v1/ai/match with the current user's session cookie. The response is a list of {job_id, score} rows; the JS renders the matching job cards.

If Pro is inactive or AI is disabled, the block silently returns an empty result set - no broken markup, no PHP notice, no JS error.

AI Description Writer (Free hook, Pro behaviour)

The post-a-job form has a "Generate with AI" button next to the description editor. It's gated behind the wcb_ai_description_enabled filter:

// In Free's blocks/job-form/render.php
if ( apply_filters( 'wcb_ai_description_enabled', false ) ) : ?>
    <button ... data-wp-on--click="actions.generateDescription">
        Generate with AI
    </button>
<?php endif;

Pro's AiModule::is_enabled() returns true for this filter when a provider + API key are configured. An add-on can short-circuit Pro and ship its own driver:

add_filter( 'wcb_ai_description_enabled', '__return_true' );

When clicked, the JS calls POST /wcb/v1/jobs/ai-description with title, company_type, and location from the form. The response returns {description: "..."} which the JS injects into the editor.

REST endpoints (shipping in 1.1.1)

Four AI endpoints exist. All live in api/endpoints/class-ai-endpoint.php and inherit from WCB\Pro\Api\ProRestController.

Method Route Permission Body / Query
POST /wcb/v1/ai/match logged-in user none - implies current user
GET /wcb/v1/candidates/{id}/matches own candidate row OR wcb/manage-ai path id
GET /wcb/v1/ai/ranked-applications/{job_id} wcb/view-applications path job_id
POST /wcb/v1/jobs/ai-description wcb/post-jobs title, company_type, location

Rate limiting

Every endpoint applies a transient-based 30 calls per user per hour ceiling. Hitting the cap returns:

{
  "code": "wcb_rate_limit",
  "message": "AI request limit reached. Please try again later.",
  "data": { "status": 429 }
}

This is global per user across all four endpoints. If you need a higher ceiling, override the transient logic in a child class - the limit isn't exposed as a filter in 1.1.1.

Common error codes

Code Meaning
wcb_ai_disabled (HTTP 503) Provider unset or API key missing. Returned from /jobs/ai-description; other endpoints return an empty list silently.
wcb_rate_limit (HTTP 429) Per-user hourly ceiling hit.
rest_forbidden (HTTP 403) Caller lacks the ability check.

Filters Pro fires (shipping in 1.1.1)

Filter Args Returns Use case
wcbp_ai_provider_drivers array $builtin, string $api_key, string $base_url array of slug => factory_callable Register a custom AI provider driver.
wcbp_ai_provider_requires_api_key bool $requires_key, string $provider bool Override whether the active provider needs an API key. Useful for self-hosted vLLM / on-prem gateways.
wcbp_candidate_resume_data int $user_id array<string, list<array<string, string>>> (group => entries) Return the resume data shape for matching / ranking. Add-ons hooking Pro's resume builder satisfy this so AI can consume it.

Filter Pro consumes from Free

Filter Where Effect
wcb_ai_description_enabled Free blocks/job-form/render.php Pro's AiModule::is_enabled() returns true when a provider + key are configured.

Action hook Pro listens to

Hook Where What Pro does
wcb_job_created Free fires after a job post is created Pro's AiModule::generate_job_embedding() embeds the title + content and stores in wcb_ai_vectors.

Pro does not fire any custom do_action events around the AI flow in 1.1.1. If you need to observe an AI operation (e.g. log every embedding cost), wrap the relevant call yourself or extend AiEndpoint in a child class.

Abilities used by AI endpoints

These are the WordPress Abilities (registered under the wcb/ namespace) the AI endpoints check:

Ability Used by
wcb/manage-ai /candidates/{id}/matches when the caller isn't the candidate
wcb/view-applications /ai/ranked-applications/{job_id}
wcb/post-jobs /jobs/ai-description

Grant the underlying capability (wcb_view_applications, wcb_post_jobs, etc.) - the Abilities API reads it. See ../admin-guide/14-capabilities-and-roles.md.

The AiModule public API

If you're writing a Pro add-on that needs to talk to AI directly:

use WCB\Pro\Modules\Ai\AiModule;

$ai = new AiModule();

// Quick check before doing anything else.
if ( ! $ai->is_enabled() ) {
    return;
}

// Top-N job matches for a candidate.
$matches = $ai->match_candidate_to_jobs( $user_id, 10 );
// Returns: list<array{job_id: int, score: float}>

// All applications for a job ranked by AI score.
$ranked = $ai->rank_applications( $job_id );
// Returns: list<array{application_id: int, score: int, reason: string}>

// Direct provider access (for custom prompts).
$driver = $ai->get_driver();
$reply  = $driver->complete( 'Your prompt here' );
$vector = $driver->embed( 'Text to embed' );

Each call goes through the configured provider (openai, claude, ollama, or one registered via wcbp_ai_provider_drivers).

Registering a custom AI provider

To ship a driver for Cohere, Mistral, a private LLM, etc., implement AiDriverInterface and register it via the filter:

<?php
namespace MyAddon\AI;

use WCB\Pro\Modules\Ai\AiDriverInterface;

class CohereDriver implements AiDriverInterface {

    public function __construct( private string $api_key ) {}

    public function embed( string $text ): array|\WP_Error {
        // Call Cohere embed endpoint; return float[] vector
        // or WP_Error on failure.
    }

    public function complete( string $prompt, array $options = array() ): string|\WP_Error {
        // Call Cohere chat endpoint; return string or WP_Error.
    }

    public function provider_name(): string {
        return 'cohere';
    }
}

add_filter(
    'wcbp_ai_provider_drivers',
    function ( array $drivers, string $api_key, string $base_url ): array {
        $drivers['cohere'] = static fn(): AiDriverInterface
            => new \MyAddon\AI\CohereDriver( $api_key );
        return $drivers;
    },
    10,
    3
);

Once registered, "Cohere" becomes a valid value for the wcbp_ai_provider option - set it in the AI Settings tab or via WP-CLI / direct option update.

What 1.1.1 does NOT ship (set expectations honestly)

Several capabilities that you might expect from a "modern AI job board" are not in 1.1.1. Listed so add-on authors know where to focus and customers aren't surprised:

  • Resume parsing - the filter wcbp_candidate_resume_data exists so an add-on can supply parsed data, but Pro does NOT ship a resume-parser. The data flow assumes whatever produces the resume data hooks the filter.
  • No AI fit-score column on the applications admin screen - the REST endpoint /ai/ranked-applications/{job_id} returns the data, but the admin column UI isn't registered. Render it yourself via a custom column registration if you need it.
  • No shortcode wrapper for the AI block - the block is block-editor / page-builder only in 1.1.1.
  • No WP-CLI command surface for AI - the WP-CLI namespace wp wcb ai * does not exist.
  • No background indexer / reindex button - embeddings are generated once at wcb_job_created only. Existing jobs from before AI was enabled do NOT auto-backfill. If you need backfill, iterate jobs and call AiModule::generate_job_embedding() directly.
  • No "Test connection" button - configuration is validated only when a real AI call is made.
  • No action hooks around the AI lifecycle (no wcbp_ai_job_embedded, no wcbp_ai_application_scored, etc.). If you need to observe these events, wrap the public AiModule methods in your add-on.

These are honest gaps, not bugs - they're features queued for a later release. If any are blockers for your use case, file on the support board so they get prioritised correctly.

Where to go next

AI Troubleshooting

What can go wrong with AI features in 1.1.1, in order of how often it actually happens.

If you're on Free and don't see the AI Settings tab at all - that's expected, not a bug. AI Settings only appears with Pro active and licensed.

"Invalid API key" / "Authentication failed"

The most common setup error.

Check:

  1. Right key for the right provider. OpenAI keys start sk-, Anthropic keys start sk-ant-, Ollama doesn't use a key. Copy from the provider dashboard, not from a stale email.
  2. No leading / trailing whitespace. Particularly when pasting from a terminal - a hidden newline breaks auth.
  3. Key isn't disabled or expired. Confirm on the provider dashboard. OpenAI shows last-used time, useful for spotting an accidentally-revoked key.
  4. Right organisation / project (OpenAI). If your OpenAI account has multiple projects, the key must belong to the project that has the billing source attached.

If the key works in curl but not in the plugin, check wp-cron isn't being blocked by a host firewall stripping outbound HTTPS to non-whitelisted domains.

"Quota exceeded" / "Rate limit hit"

Three different things can produce this kind of error:

Provider-side monthly cap

OpenAI: Dashboard → Limits → check current usage vs. cap. Raise the monthly cap (Billing → Limits) or wait for the next billing cycle.

Anthropic: Console → Limits → adjust monthly cap.

Ollama: Doesn't have a quota - but it can run out of memory. Watch dmesg for OOM-killer events.

Provider-side per-minute rate limit

If you see HTTP 429 from OpenAI / Anthropic, you're hitting their per-minute or per-day rate ceiling. Reduce concurrent calls (e.g. slow down a bulk backfill loop).

Plugin-side rate limit (Pro)

The AI endpoints enforce a 30 calls per user per hour ceiling via transients. Response:

{
  "code": "wcb_rate_limit",
  "message": "AI request limit reached. Please try again later.",
  "data": { "status": 429 }
}

This is shared across all four AI REST endpoints per user. Heavy testing during setup will hit it. Wait an hour, or in dev clear the transient:

wp transient delete "wcbp_ai_rate_{user_id}"

"Connection refused" (Ollama)

Ollama isn't running, isn't reachable from the WP host, or the Base URL is wrong.

  1. Is the Ollama service up? systemctl status ollama (or ps aux | grep ollama).
  2. Is it bound to the right address? Default is localhost:11434. Test from the WP host: curl http://localhost:11434/api/tags.
  3. Are the required models installed? ollama list should show both nomic-embed-text and llama3. If not: ollama pull nomic-embed-text && ollama pull llama3.
  4. If Ollama is on a different server, the Base URL needs to point there AND Ollama needs to bind to that interface (OLLAMA_HOST=0.0.0.0:11434 systemctl restart ollama).

AI Chat Search returns no results

Several possibilities:

No embeddings exist yet

Embeddings are generated only at wcb_job_created in 1.1.1. Jobs that existed before AI was turned on have no vectors. They won't appear in AI Chat Search.

Fix: backfill manually. See the 02-setup-and-providers.md section for the WP-CLI snippet.

Provider was switched

If you changed providers (e.g. OpenAI → Ollama), the dimension count changes (1536 → 768). Cosine similarity returns 0 for every mismatched pair, so search returns nothing. Re-embed all jobs against the new provider using the same backfill snippet.

The query is too short / too vague

The block renders results from match_candidate_to_jobs, which embeds the query and returns top-10 by cosine. Very short queries ("dev") return whatever's broadly closest - usually not useful. Tell candidates to type at least a phrase.

Provider call failed silently

AiModule::match_candidate_to_jobs() returns an empty array on any provider error. Check wp-content/debug.log for entries matching wcb_ai or wcbp_ai around the time of the failed search.

AI Description Writer button is missing

  1. Pro inactive / unlicensed. Check Career Board → Settings → License.
  2. Provider not configured. AI Settings → Provider must be set to something other than None/Disabled, AND a valid API key (or Base URL for Ollama) must be saved.
  3. Employer doesn't have wcb_post_jobs. Check via wp user list-caps {login} | grep wcb_.
  4. wcb_ai_description_enabled filter is returning false. An add-on may be overriding it. grep -rn "wcb_ai_description_enabled" wp-content/plugins/ to see who's hooking it.

Description Writer returns gibberish / wrong language

  1. Provider quality. Ollama / llama3 is the weakest writer of the three. Switch to OpenAI or Claude for production use; keep Ollama for local-only privacy use cases.
  2. Inputs are sparse. The writer uses only title, company_type, and location from the form. Vague inputs produce vague output.
  3. Wrong language. The AI generates in the same language as the inputs. To get a French description, write title / company / location in French.

"AI is not configured" (HTTP 503)

Returned by POST /wcb/v1/jobs/ai-description when:

  • Provider is unset (wcbp_ai_provider is empty or none).
  • Provider is set but the matching credential (wcbp_ai_api_key for OpenAI / Claude, wcbp_ai_base_url for Ollama) is empty.

Open AI Settings, confirm both fields are populated, save.

Application ranking returns zero scores across the board

Almost always means wcbp_candidate_resume_data filter isn't satisfied. Pro core does NOT ship a resume-parser; this filter is the integration point an add-on should hook to supply candidate data for the AI to score against.

Without the filter being satisfied, the AI receives empty strings and returns low scores for everyone.

Fix: install or write an add-on that hooks wcbp_candidate_resume_data, accepts a $user_id, and returns an array of resume sections. The AiModule::resume_to_text() flattens it into a space-separated string for the prompt.

Application ranking endpoint returns 403

The caller doesn't have wcb_view_applications. Grant via:

wp user add-cap {login} wcb_view_applications

or use a role manager plugin to add the capability to the relevant role.

"Provider returned empty response"

Rare. Either:

  1. The provider hit an internal error and returned an empty body. Retry the action - usually transient.
  2. The plugin's wp_remote_request got a connect timeout.
  3. (Ollama) The model is still loading on first request after server restart. Try once more - subsequent requests are fast.

AI spend is suddenly higher than expected

  1. Manual backfill running. If someone ran the WP-CLI backfill snippet recently, that's the cost.
  2. A loop or accidental cron. Check OpenAI / Anthropic dashboard activity for spike timing. Grep your custom plugins for hooks on wcb_job_created - if a custom plugin re-saves jobs frequently, each save fires an embedding call.
  3. OpenAI dashboard → Activity shows request counts per day. If the spike doesn't match a known event, set the monthly cap to a safe number and investigate.

Disable AI quickly in an emergency

Three paths:

  1. AI Settings → Provider → None / Disabled. Save.
  2. WP-CLI:
    wp option update wcbp_ai_provider none
    
  3. Database:
    UPDATE wp_options SET option_value = 'none' WHERE option_name = 'wcbp_ai_provider';
    

All AI calls stop immediately. UI elements that depend on AI (description writer button, chat search results) hide cleanly. No data is lost.

Things that look broken but aren't

Listed because they regularly get filed as bugs:

  • No "Test connection" button. Not built in 1.1.1. Verify via a real generation.
  • No "Indexed X of Y jobs" counter. No bulk indexer ships. Existing jobs don't auto-backfill on first enable.
  • No AI fit-score column on the applications admin screen. REST data is available; the UI column is queued for a later release.
  • No wp wcb ai * WP-CLI commands. Use direct PHP via wp eval if you need to drive AI from the CLI.
  • No wcbp_ai_job_embedded / wcbp_ai_*_completed action hooks. No observability hooks fire from AI in 1.1.1.

These are real gaps, not bugs - filing a "missing feature" report against them is fine and goes into the backlog.

How to file an AI bug report

If something genuinely doesn't work and these steps didn't help, file on the support board with:

  1. The provider you're using (OpenAI / Claude / Ollama).
  2. What you did to trigger the issue (exact buttons / queries).
  3. What you expected vs. what you saw.
  4. Anything from wp-content/debug.log matching wcb_ai or wcbp_ai.
  5. The provider dashboard activity log timestamp around the failure (helps correlate with API-side issues).

Don't include actual candidate resumes or full applicant data - shape, not contents.

Where to go next

Pro Features

Pro-only capabilities included with the Pro plugin.

Job Map

Pro feature - Requires WP Career Board Pro.

The Job Map block displays an interactive map of job locations alongside your listings. As candidates filter jobs, the map updates in real time - no page reload.

How It Works

The Job Map shares the same search state as the Job Listings and Job Filters blocks. When a visitor searches by keyword, filters by category, or selects a job type, the map instantly updates to show only matching pins.

Clicking a pin on the map opens a small popup with the job title and a "View Job" link.

Requirements

  • Jobs must have a Location set (city, region, or full address)
  • The location is geocoded automatically when the job is saved

No API key is required. The map uses Leaflet with OpenStreetMap tiles - it works out of the box.

Adding the Job Map

  1. Open your jobs page in the WordPress editor
  2. Click + and search for "Job Map"
  3. Insert the block

Recommended layout - two columns with Map on the left, Listings on the right:

[ Job Search ] [ Job Filters ]
[ Job Map     ] [ Job Listings ]

This gives candidates both a spatial view and a list view simultaneously.

Block Settings

Setting Default Description
Map Height 480px Height of the map canvas in pixels

Remote Jobs

Jobs posted as Remote appear in a special "Remote" cluster rather than a specific geographic pin, keeping the map accurate for fully remote roles.

Multi-Board Engine

Pro feature - Requires WP Career Board Pro.

The Multi-Board Engine lets you run multiple independent job boards from a single WordPress install. Each board has its own set of jobs, employers, and settings - all managed from one admin.

What You Get

  • Multiple boards - create as many boards as you need (e.g. "Tech Jobs", "Marketing Jobs", "Remote Only")
  • Board isolation - jobs posted to one board don't appear on others
  • Board Switcher block - a tab bar that lets visitors switch between boards on a single page
  • Per-board settings - each board can have its own pipeline stages, credit pricing, and custom fields

Creating a Board

  1. Go to WP Career Board → Boards in wp-admin
  2. Click Add New Board
  3. Fill in:
Field Description
Board Name Visible to employers when posting (e.g. "Tech Jobs")
Slug URL-friendly identifier, auto-generated from the name
Description Optional internal note
  1. Click Save

Assigning Jobs to a Board

When an employer posts a job, they see a Board dropdown in the job form (if more than one board exists). The job is assigned to their selected board.

Admins can also reassign jobs from WP Career Board → Jobs → Edit Job.

Board Switcher Block

Add the Board Switcher block to your jobs page so visitors can tab between boards:

  1. Open your jobs page in the WordPress editor
  2. Insert the Board Switcher block above the Job Listings block
  3. Save

Page layout with Board Switcher:

[ Board Switcher: All Jobs | Tech | Marketing | Remote ]
[ Job Search ] [ Job Filters ]
[ Job Listings ]

Clicking a tab updates the Job Listings block to show only that board's jobs - no page reload.

Default Board

The first board you create becomes the default. Jobs posted without a board selection go to the default board.

To change the default: go to WP Career Board → Boards and click Set as Default.

Per-Board Pipeline Stages

Each board can have its own application pipeline stages. Go to WP Career Board → Boards, open the board, and configure its stages independently.

Employer Access

Admins assign employers to one or more boards:

  1. Go to WP Career Board → Employers
  2. Click the employer's name
  3. In the Boards section, check the boards they can post to

Employers only see jobs and applications for their assigned boards.

Analytics Dashboard (Pro)

The Analytics module gives you a real-time snapshot of your job board's activity -- jobs, applications, users, views, and credit flow -- from a single dashboard screen.

Requires WP Career Board Pro with a valid license key.

What Is Tracked

Metric Description
Total Jobs Count of all published wcb_job posts
Total Applications Count of all submitted applications
Total Employers Number of users with the wcb_employer role
Total Candidates Number of users with the wcb_candidate role
Job Views (30 days) Page view events logged in the wcb_job_views table during the last 30 days
Top 5 Jobs The five most-viewed jobs, with individual view counts
Application Rate Average number of applications per published job
Credits Issued Lifetime sum of all topup entries in the credit ledger
Credits Spent Lifetime sum of all deduction entries in the credit ledger

Job view tracking is provided by WP Career Board (free). All other metrics are computed directly from WordPress post counts, user roles, and the credit ledger table.

Where to Find Analytics

Go to Career Board -> Analytics in your WordPress admin. The dashboard refreshes on each page load -- no manual refresh is required.

CSV Export

You can export the full credit ledger as a CSV file for accounting or auditing purposes.

  1. Go to Career Board -> Analytics
  2. Click Export Credit Ledger CSV
  3. A file named wcb-credits-YYYY-MM-DD.csv downloads immediately

CSV Columns

Column Description
ID Ledger row ID
Employer WordPress user ID of the employer
Amount Credit amount (positive for top-ups, negative for deductions)
Type Entry type: topup, hold, deduct, or refund
Job Associated job post ID (if applicable)
Note Human-readable note attached to the entry
Date Timestamp the entry was created

Notes

  • The credit ledger is append-only -- no entries are ever edited or deleted, so the export is a reliable audit trail
  • Job view data requires the Free plugin's wcb_job_views table; if the table is absent, view metrics show 0
  • Analytics data is not cached -- it queries the database on every page load

Job Feed / XML Syndication (Pro)

The Job Feed publishes all your live jobs as an XML feed at a fixed URL. Submit this URL to Indeed, LinkedIn, and other job aggregators to automatically syndicate your listings.

Requires WP Career Board Pro with a valid license key.

Feed URL

https://yoursite.com/wcb-jobs.xml

The feed is disabled by default. Enable it in Career Board -> Settings -> Job Feed.

Feed Format

The feed uses the Indeed XML format, which is also accepted by Glassdoor, LinkedIn, and most other major job aggregators. Each <job> entry contains:

Field Source
<title> Job post title
<date> Publication date
<referencenumber> WordPress post ID
<url> Public permalink
<company> Company name meta field
<city> First term from wcb_location taxonomy
<description> Job description (HTML stripped)
<salary> Formatted min-max range, e.g. $80,000 - $120,000 / yearly
<jobtype> First term from wcb_job_type taxonomy
<email> Contact email from feed settings
<expirationdate> Deadline meta field

Setup

Step 1: Enable the Feed

  1. Go to Career Board -> Settings -> Job Feed
  2. Toggle Enable Feed on
  3. The feed URL appears immediately below the toggle

Step 2: Set the Contact Email

Enter the email address to include in the <email> field of every job entry. This is the address aggregators and candidates use to contact you about listings. It defaults to the WordPress admin email.

Step 3: Submit to Indeed

  1. Log in to the Indeed Employer Portal
  2. Go to Integrations -> Job Feed
  3. Enter your feed URL: https://yoursite.com/wcb-jobs.xml
  4. Indeed re-fetches the feed every 24 hours

Pagination

The feed returns up to 200 jobs per page (the maximum Indeed recommends). If you have more than 200 published jobs, append a start parameter to retrieve additional pages:

https://yoursite.com/wcb-jobs.xml?start=0    <- jobs 1-200
https://yoursite.com/wcb-jobs.xml?start=200  <- jobs 201-400
https://yoursite.com/wcb-jobs.xml?start=400  <- jobs 401-600

Caching

The feed is cached for one hour using WordPress transients. When any job is saved or updated, the cache is immediately invalidated -- the next request builds a fresh feed.

Disabling the Feed

Toggle Enable Feed off. The URL returns a 404 response instead of XML. Aggregators that poll the URL will stop receiving new listings.

Progressive Web App (Pro)

The PWA module turns your job board into an installable Progressive Web App. Candidates can add it to their phone's home screen and browse job listings even with a poor connection.

Requires WP Career Board Pro with a valid license key.

What the PWA Provides

Feature Description
Install prompt Browsers prompt candidates to install the job board as a home screen app
Offline browsing Previously visited job listings load from cache when the device is offline
Network-first forms Application forms and dashboards always fetch fresh data -- never served stale from cache
Branded splash screen The app name, theme color, and icon match your site's branding
VAPID key pair Generated automatically on plugin activation for future push notification support

How It Works

The module serves two files from your site's root:

  • /wcb-manifest.json -- Web App Manifest describing the app name, icon, and display mode
  • /wcb-service-worker.js -- Service worker that intercepts fetch events on WCB pages

The service worker uses stale-while-revalidate for job listing pages (/jobs/, /companies/, /candidates/): the cached version loads instantly while a fresh copy is fetched in the background. Application forms and dashboard pages use network-first: they always try the network and fall back to cache only if the network is unavailable.

The manifest and service worker are only injected on WCB-related pages (job archives, single job pages, and the configured Employer/Candidate Dashboard pages).

Setup

Step 1: Configure the Theme Color

  1. Go to Career Board -> Settings -> Integrations
  2. Find the PWA Settings card
  3. Pick a Theme Color -- this is the brand color shown in the browser toolbar and on the splash screen when the app launches
  4. Click Save

The default theme color is #4f46e5 (indigo).

Step 2: Flush Permalinks

After first activating Pro, go to Settings -> Permalinks and click Save Changes. This registers the rewrite rules needed to serve /wcb-manifest.json and /wcb-service-worker.js.

Browser Support

The PWA install prompt and service worker work in:

  • Chrome and Edge (Android and desktop)
  • Safari 16.4+ (iOS and macOS)
  • Firefox (service worker only -- no install prompt on Firefox for Android)

Browsers that do not support service workers continue to work normally -- the module degrades gracefully.

Verifying Installation

Open your job listings page in Chrome on Android. After a few seconds, Chrome displays an Add to Home screen banner at the bottom of the browser. Tap it to install. The app opens in standalone mode (no browser toolbar) with your chosen theme color.

On desktop Chrome, look for the install icon in the address bar.

Migration and CSV Import (Pro)

The Migration module lets you bulk-import jobs from a CSV file and migrate existing listings from WP Job Manager. All imports land as Pending posts for editorial review before going live.

Requires WP Career Board Pro with a valid license key.

CSV Import

Finding the Import Screen

Go to Career Board -> Import and look for the CSV -> Jobs card (marked Pro).

Download the Sample File

Click Download Sample CSV to get a correctly structured template with two example rows. Use it as a starting point for your data.

CSV Column Reference

Required

Column Description
title Job title -- the only required column

Content

Column Description
description Full job description (HTML allowed)
status pending (default), publish, or draft
deadline Application deadline -- any parseable date format, stored as YYYY-MM-DD

Salary

Column Accepted Values
salary_min Integer (e.g. 80000)
salary_max Integer (e.g. 120000)
salary_currency USD, EUR, GBP, CAD, AUD, INR, SGD
salary_type yearly, monthly, or hourly

If salary_min is greater than salary_max, the importer swaps them automatically and records a warning.

Flags

Column Accepted Values
remote yes, no, 1, or 0
featured yes, no, 1, or 0

Company

Column Description
company Company name text
company_id WordPress post ID of an existing company post

Application

Column Description
apply_url External application URL
apply_email Application contact email

Taxonomies

Separate multiple values with commas or pipes. Terms are created automatically if they do not exist.

Column Taxonomy
categories Job category
job_types Job type (e.g. `Full-time
locations Location
experience Experience level
tags Job tags

Geo and Board

Column Description
lat Latitude (decimal)
lng Longitude (decimal)
board_id WordPress post ID of the target job board (Multi-Board)

Custom Fields

Add any field key from the Field Builder as a column header. Values are mapped to the corresponding custom field on each imported job.

Running the Import

  1. Select your CSV file using the file picker
  2. Click Import
  3. A results summary shows how many jobs were imported, skipped, and whether any warnings occurred
  4. Go to Career Board -> Jobs and review the Pending listings before publishing

Error Handling

Condition Result
File not found or unreadable Fatal error -- no rows processed
Missing title column Fatal error -- no rows processed
Row has wrong column count Row skipped, error logged in summary
Empty title on a row Row skipped, error logged in summary
Invalid currency or salary type Field skipped for that row
Invalid date Field skipped for that row

WP Job Manager Migration

If you are switching from WP Job Manager, the WPJM importer copies all job_listing posts to wcb_job posts, preserving title, content, author, and publish date.

What Gets Migrated

WPJM Field WCB Field
_job_location Location text
_job_salary Salary text
_company_name Company name
_job_expires Deadline
_remote_position Remote flag
job_listing_type terms wcb_job_type taxonomy

How to Run the WPJM Import

The WPJM importer is triggered via the REST API. Go to Career Board -> Import and use the WP Job Manager card, or call the endpoint directly:

POST /wp-json/wcb/v1/import/wpjm

The importer is safe to run multiple times. Jobs already migrated are marked with _wcb_imported_from_wpjm meta and are skipped on subsequent runs.

Integrations

BuddyPress, Reign Theme, BuddyX Pro, and other plugin integrations.

BuddyPress Integration

When BuddyPress is active on your site, WP Career Board automatically connects with it to enhance the community experience around your job board.

What You Get

  • Job board activity appears in BuddyPress activity streams
  • Employer and candidate roles map to BuddyPress member types
  • "Post a Job" and "Apply" activity updates can appear in community feeds
  • Candidate profiles link to their BuddyPress member profile

Requirements

  • BuddyPress (any recent version) active and configured
  • WP Career Board 1.0.0 or higher

Setup

No configuration required. Activate both plugins and the integration detects BuddyPress automatically.

Activity Stream Integration

When a job is published, a BuddyPress activity item can appear in the site-wide activity stream, showing the company name and a link to the job. Candidates can comment, react, or share the listing through BuddyPress activity features.

Member Types

WP Career Board registers two BuddyPress member types:

  • Employer - users with the WP Career Board employer role
  • Candidate - users with the WP Career Board candidate role

This lets you filter members in the BuddyPress member directory by their job board role.

BuddyBoss Platform

BuddyBoss Platform is fully compatible. The same integration applies - member types, activity streams, and profile links all work the same way in BuddyBoss.

Disabling the Integration

If you want BuddyPress active but don't want job board activity in the activity stream, you can disable specific activity types from BuddyPress → Settings → Activity or filter them via the wcb_bp_activity_enabled filter hook.

BuddyX Pro Integration

WP Career Board includes first-class support for the BuddyX Pro theme. When BuddyX Pro is active, the job board automatically adopts BuddyX's design system - colors, typography, card styles, and layout - without any extra configuration.

What You Get

  • Job listings cards styled with BuddyX Pro's card component
  • Dashboard panels that match BuddyX's sidebar and content layout
  • Job single page that fits seamlessly into a BuddyX Pro page template
  • Company profile page that uses BuddyX Pro's profile layout patterns
  • Button styles, form inputs, and badges inherit BuddyX Pro's design tokens

Requirements

  • BuddyX Pro theme active
  • WP Career Board 1.0.0 or higher

Setup

No configuration required. Activate both BuddyX Pro and WP Career Board, run the Setup Wizard, and the integration activates automatically.

BuddyPress + BuddyX Pro

If you are also running BuddyPress with BuddyX Pro, WP Career Board can surface job board activity in BuddyPress activity streams and member profiles. See BuddyPress Integration for details.

Customizing the Design

All WP Career Board styles are applied via the .wcb-* CSS class namespace. You can override any style by adding custom CSS to your BuddyX Pro child theme or via Appearance → Customize → Additional CSS.

Reign Theme Integration

WP Career Board includes first-class support for the Reign theme by Wbcom Designs. When Reign is active, the job board integrates with Reign's Customizer panels and design system.

What You Get

  • Job board components styled to match Reign's visual design language
  • Customizer integration - control job board colors from Appearance → Customize
  • Job listing cards, dashboards, and forms that fit Reign's layout grid
  • Compatible with all Reign add-ons (LearnDash, BuddyPress, etc.)

Requirements

  • Reign theme active
  • WP Career Board 1.0.0 or higher

Setup

Activate Reign and WP Career Board, run the Setup Wizard, and the integration activates automatically. No additional settings required.

Using Reign Customizer

With the integration active, you may find WP Career Board-specific options in Appearance → Customize under the Career Board section. These let you adjust primary colors, card border styles, and button variants to match your Reign theme configuration.

Reign Add-Ons Compatibility

WP Career Board works alongside all Reign add-ons. Running the LearnDash or BuddyPress add-ons does not affect the job board.

Custom CSS

Add overrides to your Reign child theme or via Appearance → Customize → Additional CSS. All WP Career Board styles use the .wcb-* prefix for easy targeting.

Tutorials

End-to-end walkthroughs for common job-board scenarios.

Your First Day as a Site Owner

A complete walkthrough from "I just installed the plugin" to "my first employer posted their first job and a candidate applied." Plan ~60-90 minutes for a thorough run. If you want to skim, the section headings below let you jump.

What you'll have at the end

  • A working job board at /find-jobs/, /companies/, /find-candidates/.
  • One employer account that can post jobs.
  • One candidate account that can apply.
  • Email notifications wired and tested.
  • A real test job published and a test application submitted.

Before you start

You need:

  • WordPress 6.5+ on PHP 8.1+ (the plugin checks this on activation).
  • An admin account on the site.
  • The ability to send email from the site (SMTP plugin, host SMTP, or the site already sending email reliably).
  • A theme that doesn't aggressively override .entry-content styles. Most modern themes work; some opinionated ones (Astra Pro, certain GeneratePress configs) need a custom CSS sweep - that's covered later.

If you want to test Pro features (AI, advanced credits, application pipeline, multi-board), install Pro too. The flow below assumes Free-only first, since Pro adds onto the same foundation.

Step 1 - Install

  1. Plugins → Add New → Upload Plugin. Pick the wp-career-board.zip you downloaded.
  2. Activate. The plugin spins up:
    • 3 database tables (jobs aren't a table - they're a CPT - but applications, saved jobs, and the credit ledger live in dedicated tables).
    • 3 custom roles: Candidate, Board Moderator, Banned Employer.
    • 12 custom capabilities (#capabilities-and-roles-wcb)).
    • Default pages: Find Jobs, Companies, Find Candidates, Candidate Dashboard, Employer Dashboard, Post a Job, Employer Registration.
  3. The Setup Wizard launches automatically. Don't dismiss it - walk it.

If you can't see the Setup Wizard, navigate to WP Admin → Career Board → Setup.

Step 2 - Walk the Setup Wizard

The wizard collects the four things that change per site:

  1. What's your job board for? - public job listings, internal hiring, university careers, etc. This sets reasonable defaults (e.g. internal-hiring boards default to requiring login to apply).
  2. Who can post jobs? - Editor role (default), a custom role, or anyone who registers. For most public boards, "anyone who registers gets wcb_post_jobs" is right. Internal boards usually pick Editor.
  3. How are postings paid for? - Free, credits per posting, or subscription. You can change this later. For first-day setup, pick Free unless you've already decided on a business model.
  4. Notification email - where new-application alerts go when the posting employer hasn't set a custom address. Usually the site admin email.

The wizard then verifies pages are correctly mapped (Find Jobs page exists, Candidate Dashboard exists, etc.) and offers to fix any missing slots.

Finish the wizard. You land on the main settings page.

Step 3 - Test email sending

Career Board sends ~15 different transactional emails (application received, application status changed, job published, password reset, verify your address, etc.). If your site can't send email, everything downstream breaks silently.

  1. Career Board → Settings → Notifications → Test email. Enter your own email address. Send.
  2. If you receive it within 30 seconds: green light, move on.
  3. If you don't: install WP Mail SMTP or Fluent SMTP, configure your provider (SendGrid, Mailgun, Postmark, Amazon SES, your host's SMTP), and retest.

This is the single most-overlooked step. Customers report "no applications coming in" - 70% of the time it's "applications came in, the email failed, employer never knew." Fix this on day one.

Step 4 - Set up email notifications

Career Board → Settings → Notifications. The defaults are reasonable but worth a once-over:

  • From name - usually your site name, not "WordPress."
  • From email - must match your sending domain (DMARC / DKIM / SPF). If your site is example.com, the from email should be noreply@example.com or similar.
  • New application received - to employer + admin by default. Keep both unless you have a reason.
  • Application status changed - to candidate. Keep enabled. This is the single most important candidate touchpoint after submission.
  • Welcome emails - to candidates and employers on registration. Keep enabled; the contents are friendly and customisable.

Step 5 - Add a Find Jobs link to your menu

The plugin created the pages but didn't wire your menu.

  1. Appearance → Menus.
  2. Add: Find Jobs, Companies, Find Candidates (if you want the candidate directory public), Candidate Dashboard, Post a Job.
  3. The Employer Dashboard / Post a Job links can be in the menu OR accessible only via the employer dashboard once they log in - your choice based on whether employers self-register or you onboard them manually.
  4. Save.

Step 6 - Create your first test employer

Don't post a job from your admin account - that hides bugs. Create an actual employer and test the flow.

  1. Open a private window so you stay logged in as admin in the main browser.
  2. Visit /employer-registration/ (or whatever you mapped the employer-registration page to).
  3. Register with a real email you can check (e.g. your-name+test@gmail.com).
  4. Confirm the welcome email arrives.
  5. Log in as that employer.

Step 7 - Post the first test job

Still as the test employer:

  1. Click Post a Job from the employer dashboard.
  2. Fill in:
    • Title: "Test Job - Senior Frontend Engineer"
    • Description: a paragraph or two.
    • Category: any (or create one inline).
    • Location: any city.
    • Type: Full-time.
    • Application: leave as "Apply through this site" (not "External URL"). External-URL testing comes later.
  3. Submit.

If you set the posting cost to free, the job goes straight to Published. If you set "requires admin approval," it sits at Pending Review - go back to your admin window and approve it from WP Admin → Career Board → Jobs.

Verify the job appears on /find-jobs/. If it doesn't:

  • Check the job's status (Published, not Draft).
  • Check the deadline isn't in the past.
  • Check your theme isn't redirecting /find-jobs/ somewhere.

Step 8 - Create your first test candidate

  1. Private window (or a different browser / incognito).
  2. Register from the Candidate Dashboard or from /candidate-registration/ if that page is mapped.
  3. Confirm welcome email.
  4. Log in.
  5. Fill in profile: name, headline ("Senior Frontend Engineer"), skills, location.
  6. Upload a resume PDF (any sample resume works).

Step 9 - Apply to the test job

As the candidate:

  1. Open /find-jobs/ from the candidate's logged-in browser.
  2. Click the test job.
  3. Click Apply.
  4. The application form pre-fills from the candidate's profile + resume.
  5. Add a cover-letter paragraph.
  6. Submit.

You should see a "thanks - application submitted" confirmation.

Step 10 - Verify the employer side

Back in the employer window:

  1. Employer Dashboard → Applications. The test application should be visible.
  2. Click into the application. The candidate's resume should be attached and downloadable.
  3. Email check - did the new-application email arrive at the employer's inbox? If not, return to Step 3 and fix email sending.
  4. Move the application's status to "Reviewing." Save.
  5. Candidate email check - did the candidate receive a "your application status changed" email? If not, status-change notifications are off - re-check Settings → Notifications.
  6. Move the application to "Shortlisted," then "Hired." Each one fires an email to the candidate.

Step 11 - Verify the candidate dashboard

Candidate window:

  1. Candidate Dashboard → My Applications.
  2. The test application should show status "Hired."
  3. Saved Jobs - bookmark another job from /find-jobs/. Confirm it appears here.
  4. Profile - verify the profile is editable and changes save.

Step 12 - Clean up your test data

Once you're satisfied:

  1. Delete the test job from WP Admin → Career Board → Jobs.
  2. Delete the test application from WP Admin → Career Board → Applications.
  3. Delete the test candidate account from WP Admin → Users.
  4. Delete the test employer account.

Or keep them and move them to a "test" status so you can iterate. Up to you.

What's next

You have a working board. Now you'd usually pick a direction:

Common day-one mistakes to avoid

  • Skipping the email test. Everything breaks silently if email doesn't send. Always test before you announce the board.
  • Posting jobs from the admin account. Your admin sees everything and skips role gates. Always test as a real employer / candidate.
  • Skipping the deadline. Newly posted jobs default to a 30-day deadline. If you want unlimited, change the default under Settings → Job Posting → Default deadline.
  • Not wiring the menu. Employers and candidates can't navigate if the menu doesn't link to dashboards. Easy to forget; users notice immediately.
  • Forgetting Pro's license activation. If you also installed Pro, activate the license under Settings → License or Pro features silently skip.

Employer End-to-End: Hiring with WP Career Board

A complete walkthrough of one hiring round from the employer's perspective: register, set up your company, post the role, review applicants, hire, and close out. This is what you'd hand to a new employer joining your board.

Free flow throughout. Pro-only steps are flagged inline.

What a typical hiring round looks like

Phase Time What you do
Setup Day 0 Register, set up company profile, buy credits if needed
Post Day 0 Draft the role, publish
Promote Day 0-3 Share on socials, internal channels
Review Day 3-14 Read applications, shortlist, interview
Decision Day 14-21 Make offers, mark hired, close the role
Close out Day 21+ Archive the role, manage company profile for next round

Step 1 - Register as an employer

Most boards have a public registration link. Look for one of these:

  • A button on the main job board (/find-jobs/) saying "Post a Job."
  • A link in the site menu to "Employers" or "Hire Talent."
  • A direct URL like /employer-registration/.

If you can't find it, your site admin may not have wired the link. Email them - registration is open but unlinked.

Fill in:

  • Your name and email.
  • A password (or a magic-link if the site uses that).
  • Your company name (used to create your company profile).
  • Optional: phone, role at the company.

You'll get a welcome email. Some sites require you to verify your email by clicking the link before you can post - if so, do that first. Then log in.

Step 2 - Complete your company profile

You're now in the Employer Dashboard. Before posting your first job, complete the company profile - applicants see it on every job.

Employer Dashboard → Company.

  • Logo - square or rectangular, at least 200×200, max 2 MB. PNG / JPG. Most boards display 120-200 px.
  • Banner - optional, 1200×400 or similar wide format.
  • Tagline - one sentence (under 100 chars). "Building open source developer tools" is good; "We are a leading provider of innovative solutions" is filler.
  • About - two or three paragraphs. What you do, who you serve, what's the team like. Specifics beat marketing copy.
  • Website - full URL including https://.
  • Locations - at least one city. Multi-location companies can list several.
  • Size - 1-10, 11-50, 51-200, etc. Helps candidates pre-filter.
  • Founded - year. Optional but adds trust signal.
  • Industry - pick the closest match.

Save. Open your company in a private window - you should see a public company page at /company/your-slug/. If it looks empty or wrong, go back and fix.

Step 3 - Acquire posting credits (if your board uses them)

If posting is free on this board, skip this step.

If the board uses credits:

  1. Employer Dashboard → Credits. Your current balance shows at the top.
  2. Click Buy Credits.
  3. Pick a package (1, 5, 10, 20 credits - depends on what the admin configured).
  4. Complete the checkout. WooCommerce / PMPro / MemberPress flows depend on what the site uses.
  5. After the order completes, your balance updates within 1-2 minutes (sometimes faster).

If your balance doesn't update:

  • Refresh the dashboard.
  • Check your order is marked "Completed" (not "Processing" or "Pending Payment").
  • Contact the site admin with your order number if it still doesn't show.

Step 4 - Draft and post your first job

Employer Dashboard → Post a Job.

Fill the basic info

  • Title - write the title a candidate would search for. "Senior Frontend Engineer" beats "Software Engineer III" beats "Code Wizard." Be specific without being clever.
  • Company - auto-filled from your profile. Verify it's right.
  • Job type - Full-time / Part-time / Contract / Internship / Temporary.
  • Category - one or more. Don't dump everything in "Other."
  • Location - city, state, country. If remote, set both a "Remote" flag AND a primary city (helps with time-zone matching).
  • Deadline / Apply by - the date the listing expires. Default 30 days from posting. Leave blank for "until filled" if your board supports it.

Write the description

The description is the single most important thing about the listing. A few principles:

  • Open with what the role is, not what your company does. A candidate skims this in 8 seconds - anchor them in the role first.
  • List 5-8 responsibilities as bullets.
  • List 4-6 requirements as bullets. Split nice-to-have from must- have if relevant.
  • Be honest about expectations. Time zones, on-call, travel, in-office days - say it up front, save time on both sides.
  • Salary range. If your jurisdiction requires posting salary (NYC, parts of EU, California for certain roles), include it. Even where not required, posting a range improves application quality dramatically.
  • About us / why work here - last, three or four bullets max. Don't repeat the company profile.

Pro tip: if you have Pro installed and AI Description Writer enabled, you can paste 4-6 key bullets and click Generate with AI. Always edit the output - it's a starting point, not a final draft. See ../ai-features/04-employer-ai-features.md.

Application settings

  • Apply through this site - applications come into the Employer Dashboard. Standard flow.
  • Apply on company site - an external URL. Candidates click out to your applicant tracking system (Greenhouse, Lever, Workable, etc.). The URL must start with http:// or https://.
  • Apply by email - applicants send straight to an email address. Use this only if you don't want to use the dashboard at all.

If you're new to the board, use Apply through this site. It's the only way Career Board's email + status tracking + AI scoring (Pro) all work together.

Other settings

  • Featured listing - costs extra credits / fee depending on board config. Promotes the job to the top of the listing.
  • Anonymous posting - hide the company name (useful for sensitive hires or stealth-mode startups). Candidates see "Confidential."

Click Submit Job.

Step 5 - Wait for approval (if applicable)

Some boards require admin approval for new postings. If yours does:

  • Status reads Pending Review.
  • Site admin gets an email + admin notice.
  • Approval typically arrives within 24 hours on a moderated board.

Once approved (or immediately, on auto-approve boards), status flips to Published and the job goes live at /job/your-job-slug/.

If it's been more than 48 hours with no movement, follow up with the site admin - sometimes the approval queue gets missed.

Step 6 - Promote the listing

Posting alone gets you maybe 5% of the applicants you should get. Promotion gets you the other 95%.

  • Share the URL on LinkedIn, Twitter, your company's Slack / Discord, internal company channels.
  • Set up a job alert so candidates who match the criteria get notified automatically - if the board has alerts enabled, candidates do this on their side.
  • Cross-post to one or two niche boards. Hacker News Who's Hiring, WeWorkRemotely, a Slack jobs channel, etc. Career Board has an RSS feed (/feed/jobs/) that some aggregators consume automatically.

Step 7 - Watch applications come in

Employer Dashboard → Applications.

Each application shows:

  • Candidate name and current role / headline.
  • Submitted date.
  • Status (defaults to "Submitted").
  • Resume download link.
  • Cover letter / answers to any custom questions you added.
  • (Pro) AI Fit Score 0-100 + one-line reason.

Click into an application to see the full detail and the candidate's public profile (if they made it public).

You'll get an email per application (as long as the admin has notifications wired correctly). If applications are arriving faster than you can read them in real time, set yourself a 9 AM / 4 PM block to triage rather than reacting to each email.

Step 8 - Triage applications

A simple triage pass:

  1. Status filter to "Submitted." Hides applications you've already triaged.
  2. Read each in 30-60 seconds. Focus on resume + cover letter. Don't read every detail yet.
  3. Move to "Reviewing" if you'd consider talking to them - even if not yet sure.
  4. Move to "Rejected" if it's clearly not a fit (wrong role, no right-to-work, etc.).
  5. Move to "Shortlisted" if it's an obvious "yes, let's interview."

Each status move fires an email to the candidate (good - keeps them informed). "Rejected" sends a courtesy email; you can customise the template in WP Admin → Career Board → Settings → Notifications → Email templates (admin-only).

Pro tip: if AI Fit Score is enabled, sort by it. Read top 10 first. Don't auto-reject by score - see ../ai-features/04-employer-ai-features.md.

Step 9 - Interview shortlisted candidates

The board doesn't run interviews - you do that externally. The board helps you stay organised:

  • Add notes to each application (private to your account). Use these for "interview Tuesday, follow up Friday" or interview feedback.
  • (Pro) Move applications through the Application Pipeline - a Kanban board with custom stages (Phone screen → Tech interview → Final → Offer → Hired).
  • Tag applications with custom tags if you've enabled the field builder (Pro).

Step 10 - Make a decision

When you've picked your candidate:

  1. Move to "Hired." Email fires to the candidate.
  2. Email the candidate directly with the offer - the board's "Hired" email is informational, not the offer letter. Always send the formal offer separately with details.
  3. Reject the rest. Move remaining shortlist candidates to "Rejected" with a courteous message. Some employers send a short personal email instead of relying on the template - your call.

Step 11 - Close out the role

Once filled:

  1. Edit the job → Status → "Filled" (or close it). This hides it from the public listing. Existing applications stay visible to you.
  2. (Optional) Export the applications list to CSV from Employer Dashboard → Applications → Export for your records.
  3. (Optional) Update your company profile with the new hire's role / team if you list staff.
  4. Refresh credits - buy more if you have another role coming up.

Step 12 - Build a candidate bench (Pro)

If you've installed Pro, the Find Candidates feature lets you search the candidate directory directly:

  • Employer Dashboard → Find Candidates.
  • Search by skill, location, headline, "Open to Work" flag.
  • Save candidates to a private list to revisit when a new role opens.
  • Send a short message asking if they'd be interested in your next role.

Free doesn't include outbound candidate search - only inbound (i.e. candidates apply to you).

Common employer mistakes

  • Posting and walking away. The first 48 hours after posting is when most quality applications come in. Be ready to review.
  • No salary range. You're competing for attention with listings that do disclose. Most candidates filter you out without one.
  • Slow status updates. Candidates check the dashboard for status changes. A week of "Submitted" feels like a no - they assume rejection. Move to "Reviewing" within 48 hours even if you haven't read them fully yet.
  • Rejecting silently. Sending a "Rejected" status with the default email is better than ghosting. Candidates remember employers who closed the loop and apply again for future roles.
  • Posting the same job twice. Confusing for candidates. Edit and republish the existing posting instead of creating a duplicate.

What you should walk away with

After one full hiring round you'll know:

  • How long applications take to start arriving on your specific board.
  • The ratio of applications to quality matches (helps you decide whether to widen or narrow next time).
  • What questions you wish you'd added to the application form (Pro: field builder).
  • Whether the board's defaults work for you or you need to adjust (notification settings, default deadline, etc.).

Where to go next

Candidate End-to-End: Finding a Job with WP Career Board

A complete walkthrough from "I just landed on the board" to "I got hired." This is what you'd hand to a candidate explaining how the site actually works.

Free flow throughout. Pro-only features are flagged inline.

What a typical job search looks like

Phase Time What you do
Discover Hour 0 Browse the board, get a feel for what's listed
Set up Day 0 Register, build profile, upload resume
Search Day 0 onward Find roles that fit, save them, set alerts
Apply Day 0-7 Apply to a curated shortlist, not 50 random jobs
Track Day 0-30 Watch status updates, withdraw if not interested anymore
Outcome Day 7-60 Get hired, or learn from the rejections

Step 1 - Browse before you register

Don't register first. Look around.

  1. Open /find-jobs/ on the board.
  2. Use the filters: category, location, type, remote-friendly, salary range (if Pro's salary filter is on).
  3. Read 3-5 listings that look interesting. You're calibrating: what roles does this board actually have? Are they your level? Right industry?
  4. Open a couple of company profiles to see what employers look like.

If nothing catches your eye, the board may not be the right fit for you - better to know now than after building a profile.

Step 2 - Register

When you've found roles worth applying to:

  1. Click Register or Sign Up from the candidate dashboard, or directly from the apply button on a job (most boards have an inline registration step on the apply form for guests).
  2. Fill in:
    • Name and email.
    • Password (or use a magic-link if the site uses that).
    • Optional: your current role / headline (set this - it shows on your public profile).
  3. Confirm your email if the site requires it.
  4. Log in.

Step 3 - Build your candidate profile

Candidate Dashboard → Profile.

Don't skip this - applications that come from a fully-built profile look more credible than ones from a blank account.

Core fields

  • Photo - optional but builds trust. Square, professional-ish.
  • Full name - match your resume.
  • Headline - one line describing what you do. "Senior Backend Engineer · 8 years · Go + Python" is better than "Looking for work."
  • Location - city and country. If you're open to relocating, say so in the bio.
  • About / Bio - two or three paragraphs. What you've built, what you're looking for, what you're not looking for. Be specific.
  • Skills - tag list. Add at least 8-10. Skills are what employers search by and how AI matching (Pro) finds you. "JavaScript" matters more than vague stuff like "team player."
  • Experience - at least your last two roles. Company, title, dates, 2-3 bullets per role.
  • Education - your highest degree minimum. Add coding bootcamps, certifications.
  • Languages - only relevant if you work in regions where multi-language matters.
  • Links - GitHub, LinkedIn, personal site, Dribbble, etc. At least one.

Visibility settings

  • "Open to Work" - flag that makes you discoverable in employer candidate searches (Pro). Turn this on if you want inbound outreach. Turn it off if you're employed and don't want your current employer finding your profile.
  • Public profile - controls whether your profile is viewable at /candidate/your-slug/. Defaults to off (visible only to employers you've applied to). Turn on if you want a shareable URL.

Step 4 - Upload your resume

Candidate Dashboard → Resume.

  • PDF preferred. Word docs work but PDFs render universally.
  • Max 5 MB. Smaller is better - most resumes are under 500 KB.
  • Recent date. Even if the content is unchanged, an old "last modified" date is a red flag for some employers.
  • One resume, unless you're targeting two very different role types (e.g. backend vs. data) - then upload two and pick the right one per application.

Pro tip: if the site has Pro AI enabled, click Auto-fill from resume to pre-populate your profile from the resume. Always review the parsed fields before applying. See ../ai-features/03-candidate-ai-features.md.

Step 5 - Set up job alerts

You don't want to check the board manually every day. Set up alerts:

  1. Candidate Dashboard → Job Alerts → New Alert.
  2. Keywords: "senior frontend" or "data engineer" - be specific.
  3. Location: city / country / "Remote."
  4. Frequency: daily for active job search, weekly if you're casually browsing.
  5. Save.

You'll get an email when matching jobs are posted. Set up 2-3 alerts covering your search variations.

Pro features: semantic matching widens alerts beyond exact keyword match (a "backend" alert will surface "server-side" postings). No setup needed - it just happens.

Step 6 - Search and shortlist

Once your profile is good and alerts are running, the rhythm is:

  1. Check alerts daily / weekly.
  2. Read the listings that match. Don't apply yet.
  3. Bookmark the interesting ones - click the bookmark icon. They land in Candidate Dashboard → Saved Jobs.
  4. Read the company profile for each. If the company seems wrong for you, unbookmark.
  5. Apply only to your shortlist - usually 3-8 per week is the right pace. Mass-applying to 50 listings is counterproductive.

Pro tip: if AI Chat Search is on the board, try natural language queries:

Senior React role, remote-friendly, US time zones, $130k+

The results rank by relevance, not by date. Helpful when keyword search isn't finding the right roles.

Step 7 - Apply

For each shortlisted job:

  1. Click Apply on the job page.
  2. The form pre-fills from your profile + resume. Verify it's right.
  3. Cover letter / answers - fill in any questions the employer added. Don't paste a generic letter. 4-6 sentences specific to this role beats a long generic one.
  4. Resume - use the default or upload a tailored version.
  5. Submit.

You'll get a confirmation email. The application is now visible in Candidate Dashboard → My Applications.

What to write in a cover letter (paragraph by paragraph)

If the application form has a "Cover letter" textarea (most do):

  • Paragraph 1: why this specific job. Name the role, name something specific about the company.
  • Paragraph 2: why you. One or two concrete examples from your background that match what the role needs.
  • Paragraph 3: logistics if relevant. Notice period, location, start-date constraints.

Don't:

  • Restate your resume.
  • Apologise for any gap.
  • Use "To Whom It May Concern" - the employer's name is usually on the company profile.

Step 8 - Track applications

Candidate Dashboard → My Applications.

Each row shows:

  • Job title + company.
  • Status - Submitted, Reviewing, Shortlisted, Hired, Rejected, Withdrawn, Job Removed.
  • Submitted date + last update date.

When the employer changes your status, you get an email and the dashboard updates.

What each status means

  • Submitted - they have it; no decision yet. Most applications stay here for several days before the employer looks.
  • Reviewing - they've opened it. Activity, but no decision yet.
  • Shortlisted - under serious consideration. Expect interview outreach.
  • Hired - congratulations. Confirm details with the employer outside the platform.
  • Rejected - not moving forward. The application is closed.
  • Withdrawn - you (or the system) pulled the application out.
  • Job Removed - the employer or admin deleted the job posting while your application was in flight. Your application is preserved in your history.

What to do if your application sits at "Submitted" forever

  • Most employers take 1-2 weeks to triage. Be patient.
  • After 3 weeks, you can email the employer directly through their company profile (if they listed contact) for a quick "any update?" ping. Once is fine - don't repeat.
  • After 4 weeks with no movement, assume soft rejection. Move on.

Step 9 - Withdraw if your situation changes

If you got an offer elsewhere or you're no longer interested:

  1. My Applications → click the role → Withdraw.
  2. Confirm.
  3. The employer is notified.

This frees up your "I've already applied" status - if a duplicate of the role comes up in 3 months, you can re-apply.

Step 10 - Manage saved jobs and alerts over time

Your search will shift. Update accordingly:

  • Saved Jobs - periodically clear out ones that expired or you no longer want.
  • Job Alerts - adjust keywords if your alerts are too noisy or too quiet.
  • "Open to Work" flag - turn off once you accept an offer (or any time you don't want inbound outreach).

Step 11 - Delete your account when you're done

If you've landed a job and don't want lingering data:

  1. Candidate Dashboard → Profile → Delete my account.
  2. Click the confirmation link in the email.
  3. Your account, applications, resumes, saved jobs, and alerts are permanently deleted. Employers see "Anonymous candidate" on historical applications instead of your details.

This is a GDPR / privacy compliant erasure. It's irreversible - make sure you've kept any data you wanted before clicking through.

Common candidate mistakes

  • Empty profile, single application. Employers click through to your profile when reviewing. If it's empty, the application looks half-hearted regardless of resume quality.
  • One resume, 50 applications. Tailor at least the cover letter per role. Generic = visible.
  • Following up too aggressively. One polite ping after 3 weeks is fine. Daily emails to the employer hurt your candidacy.
  • Ignoring rejection emails. Read them - sometimes employers include genuinely useful feedback or invite you to apply for a future role.
  • Forgetting to turn off "Open to Work" after landing a job. Your new employer's HR might be browsing the candidate directory and notice.

Where to go next

Monetizing Your Board

How to make money from your job board. Covers the four models WP Career Board supports, when each one is the right call, and the mechanics of setting each up.

The four models

Model What employers pay for When it fits Setup complexity
Free Nothing - postings are free Niche communities, employer-branding boards, sites where the goal is engagement not revenue Trivial
Pay-per-post A flat fee per job listing Small to medium boards with predictable per-job value Low
Credits / packages Bundles of postings purchased upfront Recruiters or agencies who post multiple times per month - cheaper per-post when bought in bulk Medium
Subscriptions Recurring monthly / annual access for unlimited (or N) postings High-volume employers, boards positioned as "Indeed for niche X" Medium

You can also combine: free for one type of role (e.g. internships), paid for premium roles, with optional "featured" upgrades on top.

Model 1 - Free postings

The simplest model. Employers register and post without paying. You fund the board through:

  • Sponsorships - a banner ad slot on the home page (your theme), sponsored by a company that wants exposure.
  • Affiliate / commission - Career Board doesn't track placements; for affiliate, integrate manually or use a third-party tool.
  • Adjacent product / service - a paid plugin, a course, a recruiting service, etc. The job board drives traffic; you sell something else.

Setup

  1. WP Admin → Career Board → Settings → Job Posting.
  2. Posting cost: set to 0 (or leave the default "Free" if that's already wired).
  3. Moderation: decide whether postings need admin approval or auto-publish. For free models, moderation is more important - spammers love free boards.

When this is right

  • You have an existing audience (community, newsletter, etc.) and the board is a service for them, not a product itself.
  • Your goal is reach, not revenue.
  • Spam is manageable through moderation.

When this is wrong

  • You need cash flow from the board.
  • You don't have time to moderate a high-volume free queue.

Model 2 - Pay-per-post (WooCommerce-backed)

Each new job posting requires payment. Most boards in this category use WooCommerce as the checkout layer.

Setup

  1. Install WooCommerce. Run its setup wizard. Configure payment gateways (Stripe / PayPal / etc.).
  2. Install Pro + activate license. Pay-per-post needs the credit ledger from Pro.
  3. Create a "Job Posting" WooCommerce product.
    • Type: Simple product.
    • Price: $29, $49, $99 - whatever your market bears.
    • Title: "Single Job Posting (30 days)."
  4. Map the product to a credit grant in WP Admin → Career Board → Credits → Mappings.
    • Adapter: WooCommerce.
    • Product: the one you just created.
    • Credits granted: 1.
  5. Set per-post cost.
    • Career Board → Settings → Credits → Default cost per job: 1.
    • Employers now need 1 credit to post a job.

Flow from the employer's perspective

  1. Employer clicks Post a Job.
  2. Form shows: "You have 0 credits. Buy 1 credit to continue."
  3. They click Buy Credits, get redirected to WooCommerce checkout.
  4. After payment, credit lands on their account (via the ledger).
  5. Back on the form, the credit auto-deducts and the job posts.

When this is right

  • You want predictable per-job pricing.
  • Most employers post 1-3 jobs per year (one-off pricing makes sense).
  • You're early days and want to gauge demand before bundling.

Variations

  • Featured upgrade - separate WooCommerce product priced higher ($99 instead of $29). Map it to "Featured upgrade" consumer in Career Board. Employers can buy it during the post flow.
  • Tiered pricing - different products per category. Senior / executive postings cost more than entry-level. Map each to a different category at the credit-mapping level.

Model 3 - Credit packages

Bulk pricing: employers buy 5 or 10 postings upfront at a discount.

Setup

  1. WooCommerce + Pro license (same as Model 2).
  2. Create multiple WooCommerce products:
    • "1 Job Posting" - $49 - grants 1 credit.
    • "5 Job Postings" - $199 ($40/each) - grants 5 credits.
    • "10 Job Postings" - $349 ($35/each) - grants 10 credits.
  3. Map each to the credit grant in Credits → Mappings.
  4. (Optional) Add expiry - credits expire 12 months after purchase (Pro has this on the credit-mapping screen). Encourages employers to use them up.

Flow from the employer's perspective

  1. Employer Dashboard → Credits → Buy Credits.
  2. They see the three packages with per-post pricing visible.
  3. Pick a package, check out via WooCommerce.
  4. Credits land on their account. They post normally; each post deducts 1 credit.

When this is right

  • You have repeat employers (recruiters, agencies, staffing firms).
  • Volume discount is a real selling point.
  • You want a stable balance sheet - money upfront, postings spread over months.

Model 4 - Subscriptions

Employers pay monthly or annually for unlimited (or capped) postings.

Setup options

WP Career Board supports four membership / subscription back-ends:

Plugin Best for Setup
WooCommerce Subscriptions Mature ecosystem, lots of payment-gateway support Pro + WooSubs adapter
Paid Memberships Pro Community + content-gating + jobs in one plan Pro + PMPro adapter
MemberPress More polished membership UX, but per-feature pricing adds up Pro + MemberPress adapter
Restrict Content Pro Lightweight Custom adapter (Career Board exposes the API; not shipped)

Setup (PMPro example)

  1. Install PMPro. Configure your gateway.
  2. Create membership levels:
    • Starter - $49/month - 3 postings.
    • Pro - $199/month - unlimited postings.
    • Annual Pro - $1,990/year - unlimited postings (10-month pricing).
  3. In Career Board → Settings → Credits → PMPro mappings, set:
    • Starter level → 3 credits per billing cycle.
    • Pro level → 999 credits per billing cycle (effectively unlimited).
  4. Credits auto-grant on subscription payment (via the PMPro adapter).
  5. (Optional) Pair with Annual upfront discount - same model as Starter / Pro but annual pricing.

Flow from the employer's perspective

  1. Employer registers, picks a plan, completes subscription checkout.
  2. Credits land on their account immediately.
  3. Each billing cycle, credits refresh (subject to your "carry over unused?" policy - set this in the adapter mapping).
  4. Cancellation: subscription stops, no new credits, existing credits remain until expired or used.

When this is right

  • Your board has high-volume repeat employers.
  • You want recurring revenue, not one-time.
  • You're competing with general job boards on volume and need a business model that scales.

Combining models

Most real boards run a hybrid. Examples:

  • Free for non-profits, paid for everyone else. Filter the post-a-job form based on the user's role / membership level.
  • Free postings + paid Featured upgrade. Volume comes free, you monetize the employers who want visibility.
  • Free first posting as a trial, paid thereafter. Career Board doesn't ship this out of the box - you'd need a tiny custom plugin that grants 1 credit on first registration.

Pricing - what to actually charge

There's no universal right number, but anchors:

Board type Typical per-post price
Local / city-specific $10-$30
Niche tech (remote-friendly) $50-$200
Executive / specialty $200-$500
Internship / academic $0-$30 (often free)
Healthcare / regulated industry $100-$400

Featured upgrades typically cost 2-3× the standard price. Bundle discounts typically save 20-40% over individual purchase. Annual subscriptions typically price at 10× monthly (give 2 months free).

Start with the low end of the range. You can always raise later; lowering looks bad.

How the credit ledger handles refunds and disputes

Career Board's credit system is append-only. Every credit movement writes a row - topup, hold, deduct, refund. Nothing is edited in place.

Refund flow:

  1. WooCommerce / PMPro / MemberPress issues the refund through its own checkout flow.
  2. Career Board's adapter detects the refund event (via the *_refunded hooks) and writes a refund ledger row.
  3. The employer's credit balance reduces by the refunded amount.
  4. If the employer already posted jobs against those refunded credits, the job posts stay live - the ledger just goes negative until they buy more. (Or you can configure "rollback posts on refund" - admin setting.)
  5. For disputes that don't go through WooCommerce / PMPro (e.g. a bank chargeback handled externally), use Manual credit adjustment in the admin UI to write an offsetting row.

Tracking revenue and renewals

  • WooCommerce → Reports for order revenue.
  • PMPro → Reports for subscription metrics (MRR, churn).
  • Career Board → Credits → Ledger for the credit ledger view - filterable by employer, date, source.
  • For deeper analytics, export the ledger to CSV and analyse in your tool of choice - Career Board doesn't ship a built-in dashboard beyond the basic view.

Common monetization mistakes

  • Charging too much too early. A new board with no traffic gets zero postings if pricing matches Indeed. Start cheap, build a base, raise as you fill listings.
  • Hiding the price. Employers should see what postings cost before they register. A clear pricing page beats a maze.
  • No free option for testers. Many employers want to "try one posting" before committing to a package. Either offer a free first posting or a 7-day money-back guarantee.
  • Auto-cancelling paid jobs on subscription expiry. Confusing for both employers and candidates. Keep posted jobs live until their natural deadline; just stop new postings on expired subscriptions.
  • Not testing the buy flow. Always run a real $1 product end-to-end before going live. The ledger, the email, the credit grant, the post flow - they all need to land.

Where to go next

Community Job Board with BuddyPress

If your site already runs a BuddyPress (or BuddyBoss) community, Career Board integrates so members can post jobs from their group, candidates can be discovered by their member profile, and applications can flow through the BuddyPress activity stream. This page walks through the setup and the design decisions.

When this combination makes sense

Common patterns:

  • Industry association - a community of professionals where each member's organisation occasionally hires. Jobs posted within member-only groups, not on a public board.
  • University alumni network - alumni hire other alumni; the board lives inside the alumni community.
  • Bootcamp / cohort community - graduates support each other's job search; the board is part of the cohort experience, not a public service.
  • Vertical industry community - e.g. a developer Slack-style community where a paid plan unlocks the job board area.

If you don't already run BuddyPress, you don't need it. Career Board works fine standalone.

Prerequisites

  • WordPress 6.5+, PHP 8.1+.
  • BuddyPress 13+ (or BuddyBoss equivalent).
  • WP Career Board Free or Pro - most community features work in Free; Pro adds the Multi-Board feature that maps boards to BP groups.
  • Groups component enabled in WP Admin → BuddyPress → Components.
  • Activity Streams component enabled if you want activity broadcasts.
  • Member Types if you want member-type-specific visibility (Pro).

Architecture: how Career Board and BuddyPress fit together

Career Board uses boards as a high-level container for jobs. A board can be:

  • Public - visible to everyone, jobs listed on /find-jobs/.
  • Tied to a BP group (Pro) - only group members see and can post to it.
  • Member-only - anyone logged in can see and post, no group required.

The mapping is:

BuddyPress Group "Frontend Engineers"
    └── Career Board: "Frontend Jobs" (group-tied board)
            ├── Job: "Senior React at Acme"
            ├── Job: "Frontend Lead at Beta"
            └── Job: "Junior Frontend at Gamma"

Members of the "Frontend Engineers" BP group see and can post to the "Frontend Jobs" board. Non-members don't see those listings.

Pro feature. The board-to-group mapping requires Pro's Multi-Board module. Free supports a single global board only.

Step 1 - Install and verify components

  1. Activate Career Board and BuddyPress in the order: BuddyPress first, then Career Board.
  2. BuddyPress → Components - confirm "Groups" and "Activity Streams" are enabled.
  3. Career Board → Settings → Integrations - the BuddyPress integration should show as "Active" with a green checkmark. If not, deactivate-reactivate Career Board after BP is on.

Step 2 - Map a BP group to a Career Board board (Pro)

For each BP group that should have its own job board:

  1. BP group → Manage → Career Board tab (the tab appears once Pro is on).
  2. Click Create board for this group. Set:
    • Board name - usually "Group Name Jobs."
    • Slug - auto-generated from the name; tweak if needed.
    • Default category - optional; jobs without an explicit category land here.
    • Posting cost - per-board credit cost. 0 if free.
    • Visibility - Group Members Only, Site Members, Public.
  3. Save.

A new board exists, ready to receive postings. Group members navigating to the group's Jobs tab see the listing.

Step 3 - Add a Jobs tab to each group

The Career Board integration registers a Jobs tab on each group automatically. To customise:

  1. BP group → Manage → Members → Visibility.
  2. The Jobs tab is visible to all group members by default. If you want it visible only to certain member types (e.g. "Verified employer"), filter via the standard BP group permissions or use the wcbp_board_visibility filter for fine-grained control.

To rename the tab (e.g. "Hiring" instead of "Jobs"), edit the BP group nav label or use the wcbp_group_jobs_nav_label filter.

Step 4 - Member profile job-history field

Career Board adds a "Current role" + "Open to Work" pair to BP member profiles automatically when the integration is on. Each candidate's profile shows:

  • Their current role and headline.
  • Their "Open to Work" flag (publicly visible if they set it).
  • A link to their public candidate profile (/candidate/slug/).

To extend with custom fields:

  1. BuddyPress → Profile Fields - add new fields (e.g. "Years of experience," "Preferred work mode").
  2. These fields are stored as standard BP XProfile data. Career Board reads them via the wcb_candidate_profile_fields filter to include in candidate searches.

Step 5 - Activity broadcasts

When a member posts a job or applies for a job, Career Board can broadcast that to the activity stream. Each event is configurable:

Career Board → Settings → Integrations → BuddyPress → Activity.

Event Default What it broadcasts
Job posted Off "[Member] posted a new job: [Title] at [Company]."
Application sent Off (privacy) "[Member] applied for [Job Title]."
Hired Off (privacy) "[Member] was hired for [Job Title]."
New company joined On "[Member] added a company: [Company Name]."

Application-side activity is off by default - most job searches are private. Turn on at your discretion. If you do enable, double-check your privacy policy reflects it.

Step 6 - Notifications via BP

Career Board integrates with BuddyPress's bell notifications. By default, these fire as BP notifications in addition to standard email:

  • New application on your job → bell notification.
  • Application status changed → bell notification.
  • New job posted in your group → bell notification (if member of the group's board).

To toggle individual events: Career Board → Settings → Notifications → Channels - pick "BP notifications" alongside email.

Step 7 - Member types and gating (Pro)

If your BP install uses Member Types (e.g. "employer," "candidate," "student," "alumni"), Career Board can gate posting capability and board visibility by member type.

Career Board → Settings → Permissions → Member Type Gating.

Example mapping:

  • Member type "Verified employer" - can post jobs to any board.
  • Member type "Student" - can apply to jobs marked "Open to students."
  • Member type "Alumni" - can post AND apply, full access.
  • Default - applies to anyone not in a member type.

This requires Pro and a one-time custom mapping configuration.

Step 8 - Test the integration end-to-end

The standard test path:

  1. Create two test BP user accounts: one "employer," one "candidate" / member.
  2. Add both to a BP group, then map that group to a Career Board board.
  3. As employer: post a job to that board from the group's Jobs tab. Confirm it appears on the group's Jobs listing.
  4. As candidate: navigate to the group's Jobs tab. See the listing. Apply.
  5. Back as employer: receive the application notification (email AND BP bell).
  6. Move through statuses. Candidate receives matching notifications.
  7. Verify: a non-member of the group navigating to /find-jobs/?wcb_board=group-frontend gets "not authorised" (or "redirect to login" depending on board visibility setting).

Common patterns

Pattern 1: closed community with multiple sub-boards

Run a paid community where membership unlocks job board access. Each sub-group has its own board.

  • PMPro / MemberPress + BP for the paywall.
  • Multi-Board (Pro) for per-group boards.
  • Job posting cost = 0 in credit settings (membership is the paywall, not per-post fees).

Pattern 2: open community, restricted hiring

Anyone can join the community and view jobs. Only verified employers can post.

  • BP open registration.
  • Career Board roles: candidate role auto-assigned on registration.
  • "Verified employer" role requires manual admin approval (or use the wcb_employer_default_role filter to set a "pending verification" state).

Pattern 3: alumni network

Members are organised by graduation year. Each year cohort has a group with its own job board.

  • BP groups named by year.
  • One board per year group.
  • Some boards public for cross-year networking, others private.

Troubleshooting

Jobs tab missing from BP group

  1. Career Board is active AND Pro is active AND license is valid.
  2. The group is mapped to a board in Group Manage → Career Board.
  3. The current user has permission to see the tab (member of the group OR the board is set to "Site Members" / "Public").
  4. The integration is enabled in Settings → Integrations → BuddyPress.

Member sees jobs they shouldn't

Board visibility is set too permissively. Check:

  • Multi-Board → Boards - the board's "Visibility" field. Should be "Group Members Only" for group-tied boards.
  • Members listed in the group - make sure the user isn't in the group when they shouldn't be.

BP notification not firing on application

  1. Settings → Notifications → Channels has "BP notifications" on.
  2. The receiving user has BP notifications enabled in their account settings.
  3. The BP notification component is active.
  4. Test with wp cron event list - Career Board fires notifications through standard hooks, BP picks them up immediately.

Activity stream missing the job-posted event

  1. Activity broadcasts for "Job posted" is on in Settings → Integrations → BuddyPress → Activity.
  2. The Activity Streams component is enabled in BP.
  3. The job was posted from within a BP group (not from the global Post a Job page) - the activity event only fires when the post originates from a group context.

Where to go next

Migrating from Another Job Board Plugin

If you already run a job board on WordPress with WP Job Manager, Simple Job Board, WP Jobster, or a similar plugin, you can migrate to WP Career Board without losing data or breaking your existing URLs. This page walks through the path.

Before you migrate - make these decisions

  1. Same URL structure or new one? The old plugin used /job/{slug}/ or /jobs/{slug}/. Career Board defaults to /job/{slug}/ (same as WP Job Manager). If your old structure differs, set up redirects so the old URLs still work - covered below.

  2. Move applications and candidate accounts, or only jobs?

    • Jobs only is the fast migration: ~30 minutes.
    • Jobs + applications + candidate accounts is the slow migration: 1-3 hours, more variables.
  3. Hard cutover or soft?

    • Hard: deactivate the old plugin the moment Career Board is ready. URLs flip in one window.
    • Soft: run both plugins for a couple of weeks; the old plugin handles existing listings; new postings go through Career Board. Migrate old listings on a schedule.
  4. Same theme or new? If your old plugin had a heavily-customised template, your theme likely has overrides for it. Plan a quick visual QA after switching.

Migration paths by source plugin

From WP Job Manager (Astoundify / Automattic)

The most common migration. Career Board ships a Pro Migration module that handles WP Job Manager directly.

Prerequisites:

  • WP Career Board Free + Pro both installed and active.
  • Old WP Job Manager still active during the migration.

Path:

  1. Career Board → Migration → From WP Job Manager.
  2. Pre-flight check: the tool inventories everything to migrate:
    • Jobs (CPT job_listingwcb_job)
    • Companies (post meta _company_name → CPT wcb_company)
    • Categories (taxonomy job_listing_categorywcb_job_category)
    • Types (taxonomy job_listing_typewcb_job_type)
    • Regions (taxonomy job_listing_regionwcb_job_region)
    • Applications (if you also had WP Job Manager Applications add-on)
  3. Review the inventory. Untick anything you don't want migrated.
  4. Click Migrate. The tool runs in batches of 50 (configurable). A progress bar shows; you can pause and resume.
  5. Verification step: open /find-jobs/ in a new tab. You should see all old jobs. URLs are preserved (Career Board sets the slug to the old job's slug, so /job/senior-engineer/ stays /job/senior-engineer/).
  6. Deactivate WP Job Manager when you're confident.
  7. Test apply flow as a candidate - important because the apply form is the most common breakage point.

What doesn't transfer automatically:

  • Resumes uploaded through WPJM Resumes add-on - these need a separate import step (Career Board → Migration → WPJM Resumes).
  • Bookmarks/saved jobs in WPJM - the data model is different; bookmarks reset.
  • Custom fields added through WPJM Field Editor - the migrator detects them but maps them as raw meta. Use Pro's Field Builder to recreate the fields in Career Board and the data populates.

From Simple Job Board (PressTigers)

Less common but supported.

Path:

  1. Career Board → Migration → From Simple Job Board.
  2. Pre-flight check - Simple Job Board uses CPT jobpost and taxonomies jobpost_category + jobpost_location.
  3. Run the migration. Same batch flow as WP Job Manager.
  4. URL note: Simple Job Board uses /jobs/ (plural) as the archive slug. Career Board's default is /find-jobs/. If you want to keep /jobs/, change Career Board's archive slug in Settings → Permalinks → Job Archive Slug before activation.
  5. Add redirects for /jobpost/{slug}//job/{slug}/ if you want old links to keep working.

From WP Jobster (themeforest)

WP Jobster is heavier than the other two - it includes a payment gateway, freelancer support, employer/candidate dashboards, etc. The migration covers the job-board parts; the freelancer marketplace parts are out of scope.

Path:

  1. Career Board → Migration → From WP Jobster.
  2. Pre-flight check: jobs, companies, candidates, applications.
  3. Payment / credit data: Jobster's credit system has different semantics; Career Board's adapter approximates by migrating the employer's current balance to a single topup row. Historical transactions don't transfer.
  4. Run migration.
  5. Plan extra time for theme migration - most Jobster sites use the Jobster theme, which has heavy template overrides. You'll likely need to switch theme or do CSS work after the migration.

From a custom / unsupported plugin

If your old plugin isn't in the supported list:

  1. Export old data to CSV - most plugins have an export tool; if not, query the database directly:
    SELECT post_title, post_content, post_date, post_status
    FROM wp_posts WHERE post_type = 'your_old_cpt';
    
  2. Use the Career Board CSV importer in WP Admin → Career Board → Import.
  3. Map CSV columns to Career Board fields.
  4. Run import. Career Board creates one wcb_job per CSV row.

Custom-plugin migrations are more art than science - budget extra time and test thoroughly.

Preserving URLs (redirects)

Most plugins use different URL patterns. To avoid breaking SEO:

Old plugin Old URL pattern Career Board pattern Redirect needed?
WP Job Manager /job/{slug}/ /job/{slug}/ No - slugs preserved
Simple Job Board /jobpost/{slug}/ /job/{slug}/ Yes
WP Jobster /jobs/{slug}/ /job/{slug}/ Yes
Custom CPT varies /job/{slug}/ Yes

Setting up redirects

Option A - Redirection plugin (recommended)

  1. Install Redirection.
  2. Add a regex rule:
    • Source: /jobpost/(.*)$
    • Target: /job/$1
    • 301 permanent.
  3. Verify with a sample URL in Redirection's "Check Redirect" tool.

Option B - .htaccess (Apache)

RewriteRule ^jobpost/(.*)$ /job/$1 [R=301,L]

Option C - Career Board's built-in redirect map

If the Migration module was used:

  1. Career Board → Migration → URL Map.
  2. The tool generated a list of old→new slug pairs.
  3. Toggle "Activate redirect rules" - Career Board serves the 301s from PHP. No plugin needed.

Testing the migration

A solid test path before going live:

  1. Staging copy first. Run the migration on a staging copy, not live, the first time. Spend a day kicking the tires.
  2. Sample 20 random old listings. Verify each one rendered correctly on Career Board. Check:
    • Title, description (formatting preserved).
    • Featured image (if any) carried over.
    • Application form works.
    • Old URL redirects to new URL.
  3. Test the apply flow as a fresh candidate. The most common regression: the old plugin used a different field schema, and the application form expects fields the import didn't set.
  4. Run a few search queries that worked on the old board. The results should be similar (Career Board's search is different - not pixel-identical results, but the relevant jobs surface).
  5. Run an SEO crawl. A simple ScreamingFrog scan against the new site catches broken redirects, missing meta, lost canonicals.
  6. Email your top 20 employers and top 100 candidates a week before the cutover, telling them what's changing and what to expect (their login still works, their data is preserved, the URL of their saved searches may change).

After migration

Once live:

  • Monitor the error log for the first 48 hours. Edge cases surface as PHP notices or warnings - check wp-content/debug.log for anything Career Board-related.
  • Watch for support tickets about login issues. The user account table is unchanged, but roles / capabilities may have shifted (your old plugin might have used pgs_employer as a role; Career Board uses capabilities, not custom roles for employers).
  • Update the FAQ / help docs on your site - old links, old screenshots, old terminology.
  • Set a 30-day reminder to deactivate redirects you no longer need (after most traffic has stopped hitting old URLs).

What you'll likely have to rebuild

Some things don't migrate cleanly because the underlying models differ:

  • Email templates - Career Board ships its own; old plugin's custom subject lines / branding need to be re-created.
  • Application form field order - Career Board's order is consistent (name, email, resume, cover, custom fields); if your old plugin had a custom layout, re-create with the Field Builder.
  • Theme template overrides - old plugin's templates won't apply to Career Board's blocks. If you had heavy theme customisation, you may need to redo it with Career Board's filter hooks instead.
  • Integration with third-party tools - Zapier connections, ATS integrations, etc. The Career Board REST API is well-documented; you'll rebuild the integrations against the new endpoints.

Where to go next

Multi-Language Job Board

How to run a job board that serves multiple languages, using either WPML or Polylang. Covers translation strategy, how jobs and applications behave across languages, and the gotchas to plan around.

If you only serve one language, skip this - but the same principles apply if you ever decide to expand.

Two valid strategies

Strategy 1: Mirror jobs across languages

Each job exists once per language. A "Senior Engineer" post in English has a French counterpart "Ingénieur Senior" - same role, different translation.

  • Best for: boards where the same employer hires across multiple language markets, and you want each language community to feel native.
  • Cost: the employer (or you) maintain both copies. Mismatched copies - common because translations drift - confuse candidates.

Strategy 2: Bilingual single listings

Each job exists once, in the employer's language. Candidates browse in their chosen language but see the original-language listing if no translation exists.

  • Best for: boards where roles are often remote / international and employers post in whatever language they're most comfortable with.
  • Cost: less duplication, but candidates need to be comfortable reading at least the employer's language for some listings.

Most real boards use Strategy 2 because Strategy 1 demands ongoing translation labour. Strategy 1 makes sense only when you have in-house translators or the employers translate before posting.

What translates and what doesn't

Either strategy, these elements work differently:

Element What gets translated
Job title + description Strategy 1: per copy. Strategy 2: one copy in source language.
Categories / taxonomy Always translated. "Engineering" / "Ingénierie" share the same term ID.
Locations Usually not translated (city names - "Paris" stays "Paris").
Company profiles Per profile; if a company hires in multiple languages, they translate the profile once.
Candidate profiles Per candidate; the candidate writes their bio in their language of choice.
Email notifications Per language; the candidate / employer's user preference determines which template is sent.
UI strings (block labels, buttons) Career Board ships with WPML / Polylang-compatible __() calls; the plugin shipped translation files handle UI.
Application form custom fields Per language (Pro: Field Builder).

Setup with WPML

Prerequisites

  • WPML Multilingual CMS + WPML String Translation add-on installed.
  • Languages configured in WPML.
  • WP Career Board Free or Pro.

Step 1 - Enable Career Board CPTs in WPML

  1. WPML → Settings → Post Types Translation.
  2. For each Career Board CPT, set translatable:
    • wcb_job - Translatable - use translation if available, fallback to default language.
    • wcb_company - same setting.
    • wcb_candidate - same setting if you want candidate profiles translatable; usually No (candidates write in their own language).
    • wcb_application - Not translatable (applications are written by the candidate in their language and shouldn't be duplicated).
  3. WPML → Settings → Taxonomies Translation: enable for wcb_job_category, wcb_job_type, wcb_job_region.

Step 2 - Configure custom field translation

Career Board stores job details in post meta. For each meta key WPML should sync or translate:

  1. WPML → Settings → Custom Field Translation.
  2. Recommended:
    • _wcb_job_salary_min, _wcb_job_salary_max - Copy (numbers are the same across languages).
    • _wcb_job_external_url - Copy.
    • _wcb_job_deadline - Copy.
    • _wcb_company_id - Copy.
    • _wcb_job_description_bullets (if you use them) - Translate.

If you've added custom fields via Pro's Field Builder, decide case-by-case based on whether the data is language-specific.

Step 3 - Translate UI strings

  1. WPML → String Translation.
  2. Filter by domain wp-career-board (Free) and wp-career-board-pro (Pro).
  3. Career Board ships PO/MO files for several languages; if your language is one of them, the UI strings are pre-translated. Sync them in WPML String Translation to import.
  4. For untranslated strings, edit inline in WPML and save.

Step 4 - Run a sample translation

  1. Create a job in your default language.
  2. In the post editor, find the WPML language switcher and create the translation copy. Translate the title and description.
  3. Save the translation.
  4. Test on the frontend: switch language at the top of the site → confirm the translated listing renders.
  5. Test the apply flow in the secondary language - confirm form labels are translated, the email template the candidate gets is in their language.

Setup with Polylang

Prerequisites

  • Polylang (free or Pro).
  • Languages configured under Languages → Languages.

Step 1 - Enable CPTs for translation

  1. Languages → Settings → Custom post types and Taxonomies.
  2. Check:
    • wcb_job, wcb_company, wcb_application (uncheck applications if you don't want them duplicated).
    • wcb_job_category, wcb_job_type, wcb_job_region.
  3. Save.

Step 2 - Set fallback behavior

Polylang's defaults are reasonable. Set:

  • Languages → Settings → URL modifications: subdomain, subdirectory, or query parameter. Subdirectories (/fr/) are most SEO-friendly.
  • Hide URL language information for default language - recommended unless you want /en/ prefixed for English content.

Step 3 - Translate UI strings

  1. Languages → Strings translations.
  2. Filter by group "wp-career-board" / "wp-career-board-pro."
  3. Translate each string inline.

Step 4 - Sample translation

Similar to WPML - create a translation post for a job, verify the frontend renders correctly with language switching.

Multi-language with AI features (Pro)

If you have Pro AI enabled and run a multi-language board, a few things to know:

  • Embeddings work cross-language up to a point. OpenAI's text-embedding-3-small model is multilingual - a query in French can match a job description in English with degraded but usable results. For truly cross-language search, you may want to test the embedding behavior with your specific language pair.
  • AI Chat Search shows results in the queried language's listings by default. If a candidate queries in French, only the French-side listings (Strategy 1) or the source-language listings translated to French in display (Strategy 2) are returned.
  • AI Description Writer respects the input language. If you write bullets in French, the description is in French. The AI doesn't auto-translate.
  • AI Application Ranking sends the description + candidate profile in their native languages; the model handles multilingual scoring reasonably for major language pairs but degrades for low-resource languages.

Common multi-language gotchas

Different application form submissions per language

The application form on a French job submits to the same REST endpoint as the English version. The candidate's user account is the same. Filter by _wcb_application_lang meta on the admin side if you need language-specific reporting.

Email templates per language

Career Board sends emails in the recipient's language. If the candidate registered with French as their UI language, they receive French notifications regardless of which language the job was posted in.

To verify: in Settings → Notifications → Email templates, each template should be translatable via WPML / Polylang. If not, the default language template is used as fallback.

Search engine considerations

  • Use hreflang tags so Google knows which listing serves which language. WPML / Polylang adds these automatically when configured.
  • Avoid translating the same job into too many languages if quality suffers - Google penalises auto-translated thin content.

Pro Boards (Multi-Board) and languages

If you use Pro's Multi-Board feature, each board is a separate container. You can:

  • One board per language - "English Jobs" and "French Jobs" as separate boards.
  • One board, multi-language listings within - single board, jobs per language inside.

Most teams pick "one board, multi-language listings" for simplicity. "One board per language" only makes sense if the boards serve genuinely different markets / employers / pricing.

Currency and salary

Salary is stored as a number + currency code. WPML / Polylang doesn't auto-convert. Your options:

  • Show source-currency. Display "$80k-$100k USD" regardless of UI language. Simplest, but UX-suboptimal for non-USD candidates.
  • Convert at display time. Add a custom filter (wcb_job_salary_display) that converts to the candidate's preferred currency using a third-party rate API. More work, better UX.

Slugs and URLs

When a job is translated, each translation has its own slug:

  • English: /job/senior-engineer/
  • French: /fr/emploi/ingenieur-senior/

If you want each translation's slug to match a hand-picked pattern (e.g. /fr/job/... instead of /fr/emploi/...), configure that in WPML's Permalinks settings.

Testing checklist for multi-language

Before going live:

  • Switch UI language in the header - does the job list reload with translated content?
  • Search a query in language A - do results appear?
  • Apply to a translated job - does the form show in the translated language? Does the candidate get the email in their UI language?
  • Apply to an un-translated job (Strategy 2 only) - does it work gracefully? The candidate should see the source-language listing but with translated UI chrome.
  • Employer dashboard - does it render in the employer's UI language?
  • Hreflang tags present on listing pages - view source, confirm.

Where to go next

Privacy & GDPR Compliance

A complete walkthrough of what data WP Career Board stores, how to make it GDPR / CCPA / similar-regulation compliant, and the day-to-day operations a board owner needs to handle (consent, exports, deletion requests, retention).

This is not legal advice - but it covers the technical operations that translate "be compliant" into "do this in the dashboard."

What data Career Board stores about candidates

A summary so you know what's actually on the line:

Data Where When deleted
User account wp_users table On account deletion request, or admin removal
Candidate profile (name, headline, bio, skills, location) wcb_candidate CPT post + meta With user account or on profile deletion
Resumes (uploaded PDFs) Media Library + custom resume meta With user account or via per-resume delete
Applications submitted wp_posts (CPT wcb_application) On user-account deletion: anonymised, not removed (audit trail preservation)
Cover letters and answers Application meta Same as application
Saved jobs (bookmarks) User meta With user account
Job alerts wcb_job_alerts table (Pro) With user account
IP address (on registration / apply, optional) Registration log if logging is on After 30 days unless retained for audit
Email + login history Auth logs (WP default) Per WP's standard retention
AI parse results (Pro) Candidate post meta With user account or on profile deletion
AI vectors (Pro, jobs only) wcb_ai_vectors table Jobs (not candidates) - kept until job is deleted

What data Career Board stores about employers

Data Where When deleted
User account wp_users On removal
Company profile (name, logo, about, locations) wcb_company CPT + meta With company removal
Jobs posted wcb_job CPT When the employer deletes them, or on user removal: status changes to "Job Removed," applications preserved
Credit ledger wcb_credit_ledger table NEVER auto-deleted (financial record; admin must manually purge if required)
Payment records WooCommerce / PMPro / etc. Per their plugin's deletion policy

What you legally need to do (typical GDPR baseline)

  1. Disclose what you collect in a privacy policy on the site.
  2. Obtain consent before collecting (typically a checkbox on registration / apply forms).
  3. Provide data exports when a user requests their data (right of access).
  4. Provide data deletion when a user requests it (right to erasure).
  5. Set a retention policy (don't keep data forever without reason).
  6. Notify on breach within 72 hours of detection.

The technical operations:

Step 1 - Privacy policy text

Career Board doesn't generate your privacy policy text, but here's a template paragraph to add to yours:

Job Board Data: When you register on this site as a candidate or employer, we collect the information you provide (name, email, resume, profile details, job postings, applications). We store this on our servers running WP Career Board. We use this data to show your profile / jobs / applications to relevant parties on the board. We do not sell this data. You can request a full export or deletion of your data at any time from your dashboard (Candidate Dashboard → Profile → Delete Account, or Employer Dashboard → Settings → Delete Account).

AI Features: If we have AI features enabled, your data may be sent to a third-party AI provider (OpenAI, Anthropic Claude, or Ollama on our own server) for processing. See the AI provider's own privacy policy for their handling. You can opt out of AI processing by [linking to the opt-out mechanism if you have one].

Payment Data: If you purchase services (e.g. job posting credits, subscriptions), payment is processed by [WooCommerce / PMPro / etc.] - see their privacy policy for payment data handling.

Update the bracketed bits to your specifics. Always have a lawyer review the final version.

Step 2 - Consent capture

Career Board registers a consent checkbox on the registration forms by default:

  • Candidate registration: "I agree to the Privacy Policy."
  • Employer registration: Same.
  • Guest apply form (Pro, if enabled): "I agree to share my application with the employer."

To customise:

  1. Career Board → Settings → Privacy → Consent text.
  2. Edit the text shown for each form.
  3. Toggle whether the checkbox is required (recommended: yes for both registration and apply).

The consent is logged with a timestamp on the user's account meta. To view: open the user in WP Admin → look for _wcb_privacy_consent meta.

Step 3 - Handling data export requests (Right of Access)

When a user requests their data:

Option A - User self-serves (recommended)

  1. Candidate Dashboard → Profile → Download My Data.
  2. The system generates a ZIP containing:
    • Profile fields (JSON).
    • All applications (JSON + each cover letter as TXT).
    • Resume PDFs.
    • Saved jobs (JSON).
    • Job alerts (JSON).
  3. Email link to the ZIP. The link expires after 24 hours for security.

Option B - Admin handles it manually

  1. WP Admin → Users → search for user.
  2. Tools → Export Personal Data (this is WordPress's built-in privacy tool).
  3. Career Board hooks into WP's privacy exporter, so candidate / employer / application data is included in the export.
  4. The user receives an email with a download link.

Test both paths once before going live. The most common failure: the ZIP generation hits a memory limit on shared hosting if the user has many applications. Workaround: increase WP_MEMORY_LIMIT or use the async export queue (auto-enabled for users with >100 applications).

Step 4 - Handling data deletion requests (Right to Erasure)

For candidates:

Option A - User self-serves (recommended)

  1. Candidate Dashboard → Profile → Delete Account.
  2. The system sends a confirmation email.
  3. User clicks the confirmation link.
  4. Deletion runs:
    • User account: deleted.
    • Profile fields: deleted.
    • Resumes: deleted from the media library.
    • Applications: anonymised (not deleted) - the employer still sees an "Anonymous candidate" application in their history, but no identifying data. This preserves the audit trail for the employer's compliance.
    • Saved jobs, job alerts: deleted.
    • AI parse data (Pro): deleted.

Option B - Admin handles it manually

  1. WP Admin → Tools → Erase Personal Data (WordPress built-in).
  2. Enter the user's email.
  3. Confirm the erase. Career Board hooks into WP's eraser to handle the same anonymization above.

Important - what's NOT deleted:

  • Applications are anonymised, not deleted. This is a deliberate policy choice - employers need a record of having received applications for their own compliance. The candidate's personal data is wiped, but the application row stays.
  • If your jurisdiction requires full deletion (not anonymization), override with the wcb_anonymize_or_delete filter, returning 'delete' instead of 'anonymize'.

For employers:

  1. Employer Dashboard → Settings → Delete Account (or admin manual).
  2. User account: deleted.
  3. Company profile: option to delete or transfer to another user.
  4. Jobs: status changes to "Job Removed." All linked applications transition to status "Job Removed." Applicants get a notification.
  5. Credit ledger: NOT deleted (financial record). If absolutely required by jurisdiction, admin must manually purge separately from the ledger table.

Step 5 - Retention policy

Career Board doesn't enforce automatic deletion of old data - you configure your policy:

  1. Career Board → Settings → Privacy → Retention.
  2. Options:
    • Anonymise applications older than [N] months. Strips PII from applications older than N months. Useful when applicants don't return for years but data has been stored. Default: off.
    • Delete expired job alerts after [N] months of inactivity. Default: 12 months.
    • Delete IP addresses from logs after [N] days. Default: 30.
    • Purge unsuccessful login attempts after [N] days. Default: 7.
  3. These run on a daily cron - wcb_privacy_retention_cron. Schedule visible in WP-CLI: wp cron event list | grep wcb_privacy.

Step 6 - Cookie policy

Career Board sets cookies in two places:

  1. Login cookie - standard WP authentication. Same as any WordPress site.
  2. Saved job tracking (logged-out users) - wcb_saved_jobs cookie, 90 days. Stores bookmarked job IDs so logged-out users keep bookmarks. Encrypted but not personally identifying.

Add to your cookie banner:

"wcb_saved_jobs" - saved job bookmarks for logged-out users

If you don't want this cookie, disable in Settings → Privacy → Cookies → "Allow logged-out saved jobs" - turning this off means logged-out bookmarks are not preserved.

Step 7 - AI features and data exposure (Pro)

If you have Pro AI enabled, additional disclosure is needed:

  1. Update privacy policy with a section like:

    "We use AI to power [list of features]. When you submit data (resume, profile, application), it may be sent to our AI provider ([OpenAI / Anthropic Claude / Ollama]). Their data handling is governed by [provider URL]."

  2. Per-feature opt-out (optional, custom). Add a checkbox on the apply form: "Allow AI-powered scoring of this application." Hook wcb_application_pre_save and skip AI ranking if the checkbox is unchecked.

  3. Use Ollama for sensitive data. If you can't share resume / application content with a US LLM (HIPAA, sensitive sectors), run Ollama on your server. See ../ai-features/02-setup-and-providers.md.

Step 8 - Data Processing Agreement (DPA)

For GDPR compliance, your DPA needs to cover:

  • Your role: controller (you decide what's collected).
  • Sub-processors:
    • WordPress hosting provider (e.g. SiteGround, Kinsta).
    • Payment processor (WooCommerce + Stripe / PayPal).
    • AI provider (if Pro AI is on).
    • Email service (if using SMTP plugin's provider).
  • Each sub-processor needs its own DPA, which you reference in yours.

This is paperwork, not technical setup. The plugin's role is to make sure the data flow doesn't include unexpected processors.

Step 9 - Breach response checklist

If you suspect a breach (unauthorised access, data leak):

  1. Identify scope. Which tables / files / accounts were exposed?
  2. Contain. Force-rotate all admin / employer passwords. Disable the affected user accounts if compromised.
  3. Notify affected users within 72 hours (GDPR requirement). Career Board's user list is exportable from WP Admin → Users → Export.
  4. Notify authorities if the breach meets the threshold for your jurisdiction (each EU state's DPA, ICO in the UK, etc.).
  5. Patch. Fix the underlying cause. Common causes: outdated plugin, weak admin password, compromised host.
  6. Document. Keep records of what happened, what you did, what was disclosed - for regulator audits.

Common compliance mistakes

  • No consent checkbox at registration. Easy to forget; required for GDPR. Career Board ships it on by default - make sure it's not been disabled.
  • Auto-publishing applications to BP activity stream. If you have BP activity for "applied for job" turned on, candidates may not realise their job search is public. Update consent text accordingly.
  • Storing IPs forever. WordPress core stores login IPs in the audit log indefinitely unless you configure retention. Set a retention period (recommend 30 days).
  • AI providers not disclosed. Adding Pro AI without updating the privacy policy is a quick way to be non-compliant. Always update the policy AND notify existing users of the change.
  • Half-deletion. Deleting a user but not their applications, or vice versa. Use the dashboard's Delete Account flow (or WP's privacy eraser) - don't manually delete from the database.

Where to go next

Developer Guide

Hooks reference, REST API, WP-CLI commands, and extension cookbook.

Developer Guide - Overview

WP Career Board is built to be extended. The plugin exposes ~92 hooks, 37 REST endpoints, 5 WP-CLI commands, and a JSON manifest that lets your code (or another plugin) reach into every part of the job-board flow without forking the source.

Use this guide when:

  • You're building a custom job-board theme or feature.
  • You're writing a companion plugin that integrates with Career Board (e.g. a Slack notifier, a Salesforce sync, a custom apply flow).
  • You're auditing the plugin's surface area before going live.

For customers running a job board: use the for-employers, for-candidates, and admin-guide directories instead. This section assumes you read code.

Architecture at a glance

Layer Where Purpose
Blocks blocks/<name>/render.php + view.js Customer-facing UI - server-rendered, hydrated by the Interactivity API
Shortcodes core/class-plugin.php::register_shortcodes() 1:1 wrappers around every block (page builders, classic editor)
REST API api/endpoints/class-*-endpoint.php 37 endpoints under wcb/v1/* - all extending WCB\Api\REST_Controller
Modules modules/<area>/ Feature modules: jobs, applications, candidates, employers, boards, antispam, gdpr, moderation, notifications, seo
Core services core/class-*.php Cross-cutting: Settings, Abilities, Locations, Pro coordination, Theme bridge
CLI cli/class-*-command.php wp wcb * commands - jobs, applications, migration, scale benchmark

Every layer follows the same conventions:

  • All globals prefixed wcb_.
  • All abilities use wcb/<slug> (kebab-case, namespaced).
  • All REST routes register through WCB\Api\REST_Controller.
  • All DB writes go through $wpdb->prepare().

Contents

Doc What's inside
02-hooks-reference.md Every action and filter the plugin fires, grouped by area
03-rest-api.md The full REST endpoint catalog with auth, params, response shape
04-wp-cli.md WP-CLI commands and arguments
05-extension-cookbook.md Recipes for common extension tasks

Companion plugin development

If you're building a Pro-like companion plugin, also read:

  • wp-career-board-pro/docs/website/developer-guide/02-extending-free.md
    • the canonical contract for extending Free, including the dependency guard, REST namespace sharing, and lockstep version requirements.
  • plan/INVARIANTS.yaml in either repo - machine-enforceable architectural invariants the local-CI gate checks on every commit.

Where the source of truth lives

For introspecting the plugin programmatically:

  • audit/manifest.json - canonical inventory of every block, REST endpoint, hook, CPT, taxonomy, capability, service, and CLI command. Generated by /wp-plugin-onboard. Refreshed on every release.
  • audit/journeys/ - customer-flow regression sentinels. Each journey is a Markdown file that the smoke skill walks before a release tag.
  • audit/qa-coverage.json - coverage gate tracking which REST/CLI/hook surfaces have regression tests. Pre-commit hook blocks reductions in coverage.

If you're building tooling that reads any of these, do so via the manifest's $schema - it's stable and versioned.

Hooks Reference - Actions and Filters

WP Career Board fires 29 actions and 63 filters (Free only - Pro adds its own; see the Pro developer guide). Hooks are grouped by area below.

How to use this list: every hook is fired with do_action() or apply_filters() somewhere in the plugin source. The full file:line is in audit/manifest.json#/hooks_fired. The arg signature for any hook can be found by grep against the hook name in the codebase.

Lifecycle / job posting

Hook Type Fires when
wcb_pre_job_submit Filter Before a job is created. Return WP_Error to abort.
wcb_before_create_job Filter Modify the wp_insert_post arg array before creation.
wcb_job_created Action After a job is inserted. Args: $job_id, $request.
wcb_before_update_job Filter Modify the update arg array before save.
wcb_job_updated Action After a job update completes. Args: $job_id, $request.
wcb_before_delete_job Filter Return false to abort the delete.
wcb_job_deleted Action After job is removed. Args: $job_id.
wcb_job_republished Action When a job is republished after expiry. Args: $job_id.
wcb_job_approved Action When admin approves a pending job. Args: $job_id.
wcb_job_rejected Action When admin rejects a job. Args: $job_id, $reason.
wcb_job_expired Action When the deadline passes. Args: $job_id.
wcb_check_job_expiry Action Cron hook - fires daily to expire stale jobs.
wcb_deadline_reminder Action Cron - fires the deadline-reminder email cycle.
wcb_featured_expired Action When a featured job's promotion window ends. Args: $job_id.

Lifecycle / applications

Hook Type Fires when
wcb_pre_application_submit Filter Before an application is created. Return WP_Error to abort (anti-spam, rate limits, etc.).
wcb_before_create_application Filter Modify wp_insert_post arg array.
wcb_application_submitted Action After successful submit. Args: $app_id, $job_id, $candidate_id.
wcb_application_status_changed Action When status moves (submitted → reviewing → shortlisted → rejected/hired/withdrawn/job_removed). Args: $app_id, $new_status, $old_status.
wcb_application_withdrawn Action Candidate withdrew. Args: $app_id, $job_id, $candidate_id.
wcb_application_deleted Action Application post deleted. Args: $app_id, $job_id.
wcb_application_form_fields Action Inside the apply form template - render extra <input>s here.
wcb_application_form_fields_groups Filter Add a group of custom fields to the apply form.

Lifecycle / candidates and employers

Hook Type Fires when
wcb_candidate_registered Action After a candidate signup completes. Args: $user_id, $request.
wcb_employer_registered Action After an employer signup completes. Args: $user_id, $request.
wcb_candidate_form_fields Filter Add fields to the candidate registration form.
wcb_company_form_fields Filter Add fields to the company-profile edit form.

Credits and pricing

Hook Type Fires when
wcb_credits_enabled Filter Return true if Pro credits are active.
wcb_employer_credit_balance Filter Return the current user's credit balance (Pro routes to SDK).
wcb_credit_purchase_url Filter URL the "Buy Credits" button points at.
wcb_credit_low_threshold Filter Balance below this triggers the low-credits banner.
wcb_board_credit_cost Filter Credits required to post to a board. Args: $cost, $board_id.
wcb_job_republish_credit_cost Filter Cost to republish an expired job.
wcb_moderate_jobs_ability_check Filter Return bool to override the moderation permission check.

REST response shaping

The wcb_rest_prepare_* family is your hook into every REST response. Each fires after the controller builds the row and before it's returned - modify, redact, or augment.

Hook Adjusts the response for
wcb_rest_prepare_job Single job + collection items
wcb_rest_prepare_application Single application + lists
wcb_rest_prepare_candidate Candidate profile
wcb_rest_prepare_company Company profile
wcb_job_response Legacy alias for backward compat

Pro adds: wcb_rest_prepare_board, wcb_rest_prepare_board_stage, wcb_rest_prepare_notification, wcb_rest_prepare_resume.

Block + shortcode extension

Hook Type Use it to
wcb_module_renders Filter Skip rendering of specific dashboard modules.
wcb_job_form_initial_state Filter Modify the job-form Interactivity state seed.
wcb_job_form_simple_initial_state Filter Same for the single-page job form.
wcb_job_form_fields Filter Add field groups to the job form.
wcb_job_form_step1_fields Action Inject extra <input>s into the wizard's step 1 (similar for step2/3/4).
wcb_job_form_simple_extra_fields Action Inject extra fields into the single-page form.
wcb_application_form_fields Action Inject extra fields into the apply panel.
wcb_shortcode_attr_aliases Filter Add to the camelCase ↔ lowercase attribute map (so [wcb_job_listings boardId="1"] works).
wcb_search_active_shortcodes Filter Tag/prefix names for the body-class detector. Extend if you register custom shortcodes that should also force the wcb-page body class.

Settings and pages

Hook Type Use it to
wcb_install_default_settings Filter Modify the seed values on plugin install.
wcb_settings_sanitize Filter Sanitize a custom settings key before save.
wcb_settings_tabs Filter Add a tab to the Settings UI.
wcb_settings_tab_<slug> Action Render content for a custom tab (the slug becomes the suffix).
wcb_settings_tab_antispam Action The built-in Anti-Spam tab. Hook to add additional anti-spam controls.
wcb_settings_tab_emails Action The Emails tab - extend with custom email templates.
wcb_page_settings Filter Modify which pages are mapped for "Career Board page" detection.
wcb_app_page_ids Filter Add page IDs that should get the wcb-page body class.
wcb_apply_page_class Filter Opt out a page from the wcb-page body class entirely.
wcb_apply_filters Filter Container max-width override.
wcb_container_max_width Filter Override the 1200px content-column default.
wcb_registered_emails Filter Add a new transactional email type to the plugin's email registry.

Setup wizard

Hook Type Use it to
wcb_wizard_completed Action After the wizard's last step.
wcb_wizard_force_render Filter Force the wizard to render even when is_setup_complete() is true.
wcb_wizard_complete_redirect Filter Override the URL the wizard redirects to on finish.

Pro-coordination filters (Free side)

These let Free check whether Pro is active and gate behavior. Pro hooks them to return true / version / license status.

Hook Returns
wcb_pro_active bool - is Pro plugin running?
wcb_pro_licensed bool - is the Pro license valid?
wcb_pro_version string - Pro version, e.g. "1.1.1"
wcb_pro_ai_enabled bool
wcb_pro_alerts_enabled bool
wcb_pro_resumes_enabled bool
wcb_pro_upsell_url string - where the "Upgrade to Pro" CTA points
wcb_pro_pre_check Action - fires before Pro's compatibility check
wcb_pro_settings_saved_notice Filter - message for the post-save admin notice
wcb_register_extensions Action - Pro hooks this to register its extension classes

Miscellaneous

Hook Type Use it to
wcb_industries Filter Add or rename industry categories used by the company profile.
wcb_currency_catalog Filter Add a currency to the salary-currency dropdown.
wcb_board_currency Filter Override per-board currency (Pro typically).
wcb_board_options_for_employer Filter Modify the boards dropdown shown to an employer (Pro filters to user-accessible groups).
wcb_job_board_id Filter Resolve which board a job belongs to.
wcb_job_default_status Filter Initial status on submission.
wcb_job_default_expiry_days Filter Default job-expiry window.
wcb_job_listings_api_base Filter Override the REST base for the listings block.
wcb_job_listings_query_args Filter Modify the WP_Query args for the listings server-side query.
wcb_job_listings_board_options Filter The boards visible in the listings UI's board picker.
wcb_job_listing_data Filter Per-card data (each row in the listings block).
wcb_jobs_post_filter Filter After the listings query but before render - add transformations.
wcb_jobs_allowed_meta_filters Filter Allowlist of meta keys the metaFilter block attribute may query (prevents arbitrary-meta probes).
wcb_ai_description_enabled Filter Toggle the AI-assisted description feature (Pro).
wcb_resume_archive_enabled Filter Toggle the resume directory (Pro).
wcb_theme_accent_primary Filter Primary accent color used by blocks (driven by theme integration bridge).
wcb_theme_primary_color Filter Legacy alias.
wcb_admin_email_log_response Filter Modify the email-log REST response.
wcb_cli_abilities Filter Map WP-CLI runs to ability slugs for permission checks.
wcb_import_extra_cards Action Add cards to the Import admin page.
wcb_rest_app_config Filter Frontend boot config shipped to the Interactivity API.
wcb_admin_email_log_response Filter Already listed above.

Listening pattern (example)

add_action( 'wcb_job_created', function ( $job_id, $request ) {
    // Notify a Slack channel when a new job lands.
    if ( $request->get_param( 'featured' ) ) {
        my_slack_post( "🔥 Featured job posted: " . get_the_title( $job_id ) );
    }
}, 10, 2 );
add_filter( 'wcb_rest_prepare_job', function ( $row, $post, $request, $context ) {
    // Add a `is_remote_friendly` flag based on a meta value.
    $row['is_remote_friendly'] = (bool) get_post_meta( $post->ID, '_remote_friendly', true );
    return $row;
}, 10, 4 );

How to confirm a hook signature

The fastest way to see the actual arg signature:

grep -rn "do_action\\s*(\\s*'wcb_job_created'" wp-content/plugins/wp-career-board/

That returns the file:line of every firer; open it and read the surrounding lines for the parameter shapes.

For the Pro-side hooks, see docs.wbcomdesigns.com/docs/wp-career-board-pro/developer-guide/03-hooks-reference.

REST API Reference

WP Career Board exposes 37 REST endpoints under the wcb/v1 namespace. Every endpoint extends WCB\Api\REST_Controller, which owns the shared response envelope, permission helper, and rate-limit middleware.

Authentication

Most endpoints require a logged-in WordPress user and a valid nonce. Use the standard WP REST nonce in headers:

fetch( '/wp-json/wcb/v1/jobs', {
    headers: { 'X-WP-Nonce': wpApiSettings.nonce },
    credentials: 'same-origin'
})

For server-to-server calls, generate an application password (Users → Profile → Application Passwords) and use HTTP Basic auth.

A small set of endpoints permit guest access - the apply endpoint when "Allow guest applications" is enabled in Settings, and the read-only jobs listing endpoint. Guest endpoints use the __return_true permission_callback and rely on rate-limit middleware for abuse prevention.

Response envelope

Every endpoint returns either a WP_REST_Response (success) or a WP_Error (failure). Success shape varies by endpoint; failure shape is consistent:

{
    "code": "wcb_invalid_status",
    "message": "Invalid status.",
    "data": { "status": 400 }
}

The wcb_* prefix on error codes is the plugin's namespace - addons should mirror this convention with their own prefix.

Routes by area

Jobs

Method Route Auth Purpose
GET /jobs guest OK List jobs with filters: s, category, location, type, experience, remote, salary_min, salary_max, board_id, per_page, page
GET /jobs/{id} guest OK Single job (full detail)
POST /jobs employer Create a job
PUT /jobs/{id} author or admin Update a job
DELETE /jobs/{id} author or admin Delete a job
POST /jobs/{id}/republish author Republish an expired job
POST /jobs/{id}/approve moderator Approve a pending job
POST /jobs/{id}/reject moderator Reject a pending job (requires reason)
GET /jobs/{id}/applications author or admin List applications for a job

Applications

Method Route Auth Purpose
POST /jobs/{id}/apply candidate (or guest if enabled) Submit application
GET /applications/{id} candidate or job-owner Single application detail
DELETE /applications/{id} candidate owner Withdraw application
PUT /applications/{id}/status employer/admin Change status (submitted/reviewing/shortlisted/rejected/hired)
GET /candidates/{id}/applications self or admin Candidate's application history
POST /candidates/resume-upload candidate Upload a resume PDF

Candidates

Method Route Auth Purpose
POST /candidates/register guest Register a new candidate
GET /candidates/{id} self or admin Candidate profile
PUT /candidates/{id} self Update profile
GET /candidates/{id}/bookmarks self Saved jobs
POST /candidates/{id}/bookmarks self Save/unsave a job
DELETE /candidates/account self GDPR erasure request

Employers and companies

Method Route Auth Purpose
POST /employers/register guest Register a new employer
GET /employers/{id} self or admin Employer detail
PUT /employers/{id} self Update profile
GET /employers/{id}/jobs self or admin Employer's job postings
GET /companies guest OK List companies with filters
GET /companies/{id} guest OK Single company
PUT /companies/{id} owner Update company profile

Admin and settings

Method Route Auth Purpose
GET /settings admin Read every Career Board setting
POST /settings admin Update settings
GET /admin/email-log admin Recent transactional-email send log
POST /admin/email-log/clear admin Truncate the email log

Setup wizard

Method Route Auth Purpose
POST /wizard/install-pages admin Create the 7 required pages
POST /wizard/sample-data admin Install demo content
POST /wizard/complete admin Mark wizard as finished

Modifying responses

Every Career Board response goes through a wcb_rest_prepare_* filter (see 02-hooks-reference.md) before it's returned. To add a custom field to the jobs response:

add_filter( 'wcb_rest_prepare_job', function ( $row, $post, $request, $context ) {
    $row['custom_score'] = my_score_function( $post->ID );
    return $row;
}, 10, 4 );

The $context parameter is one of single, collection, or embed - use it to tailor the response to where it's being read.

Adding new routes

The cleanest way is to extend WCB\Api\REST_Controller:

namespace MyAddon;

class My_Endpoint extends \WCB\Api\REST_Controller {

    public function register_routes(): void {
        register_rest_route(
            $this->namespace,  // wcb/v1
            '/my-thing/(?P<id>\d+)',
            array(
                'methods'             => \WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_item' ),
                'permission_callback' => array( $this, 'check_ability' ),
                'args'                => array(
                    'id' => array(
                        'validate_callback' => static fn( $v ) => is_numeric( $v ),
                        'sanitize_callback' => 'absint',
                    ),
                ),
            )
        );
    }

    public function get_item( \WP_REST_Request $request ): \WP_REST_Response {
        // ... your handler
    }
}

add_action( 'rest_api_init', static function () {
    ( new My_Endpoint() )->register_routes();
});

You get rate-limit middleware, the response envelope, and the ability-check helper for free. Route-path disjointness with the plugin's own routes is enforced by the architecture-checks gate (invariant A3 in Pro's INVARIANTS.yaml).

Rate limiting

The plugin enforces per-IP rate limits on POST/PUT/DELETE endpoints. Limits are configurable via:

add_filter( 'wcb_rate_limit_per_minute', function ( $limit, $route ) {
    if ( '/apply' === $route ) {
        return 5; // Tighter limit on apply endpoint
    }
    return $limit; // Default 20/min
}, 10, 2 );

WP-CLI Reference

WP Career Board ships 5 WP-CLI top-level commands for automation, migration, and scale testing.

wp wcb <command> <subcommand> [options]

wp wcb job

Operate on wcb_job posts.

Subcommand Purpose
wp wcb job list List published jobs with filters
wp wcb job approve <id> Approve a pending job
wp wcb job reject <id> --reason="..." Reject a job with a reason
wp wcb job republish <id> Bring an expired job back live
wp wcb job expire Run the expiry sweep manually (same as the daily cron)
wp wcb job feature <id> --days=30 Promote to featured for N days

Example - bulk reject:

wp post list --post_type=wcb_job --post_status=pending --field=ID \
  | xargs -I{} wp wcb job reject {} --reason="Duplicate posting"

wp wcb application

Operate on applications.

Subcommand Purpose
wp wcb application list --candidate_id=<id> List a candidate's applications
wp wcb application list --job_id=<id> List applications for a specific job
wp wcb application status <id> --to=<status> Update an application's status
wp wcb application withdraw <id> Withdraw an application (candidate or admin)
wp wcb application export --job_id=<id> CSV-export applications for a job

wp wcb migrate

Move content in or out of Career Board.

Subcommand Purpose
wp wcb migrate wpjm Import from WP Job Manager (Pro adds Job Manager Resume Manager import)
wp wcb migrate csv --file=<path> Bulk-import jobs from CSV
wp wcb migrate export --type=jobs Bulk-export to CSV or JSON

wp wcb scale

Production-readiness benchmarking. Per the team standard, every plugin must define hot-path query budgets and time them against a production-shape dataset.

Subcommand Purpose
wp wcb scale seed Generate 10k users × 10 rows = 100k-row synthetic dataset
wp wcb scale benchmark Time the hot-path queries; exit 1 if any query exceeds its budget
wp wcb scale teardown Drop the synthetic rows

Budgets are defined in cli/class-scale-command.php per query. PK lookups ≤5ms, indexed scans ≤30ms, snapshot reads ≤20ms.

Example - full benchmark cycle:

wp wcb scale seed && wp wcb scale benchmark && wp wcb scale teardown

The scale gate runs as stage 5.1 of composer ci. The first time you ship to production, run this against a clone of the production DB sized to your actual customer load.

wp wcb (top-level)

A few utility commands without a subcommand namespace:

Command Purpose
wp wcb version Print the installed version (handy in CI scripts)
wp wcb doctor Run a health check (page mappings, capabilities, cron schedule, debug-log diff)

Ability gating

WP-CLI runs as the system user (no current_user_can context). By default, commands skip the ability checks; for production sites you can map specific commands to abilities via the wcb_cli_abilities filter:

add_filter( 'wcb_cli_abilities', function ( $map ) {
    $map['wcb_job_reject'] = 'wcb/moderate-jobs';
    return $map;
});

When set, the CLI handler calls wp_is_ability_granted() against the configured user (--user=<login> or the system root) before proceeding.

Adding your own command

Use the same base class the plugin uses:

namespace MyAddon;

use WCB\Cli\Abstract_Cli_Command;

class My_Command extends Abstract_Cli_Command {
    protected $name = 'wcb my-thing';

    public function handle_run( $args, $assoc_args ) {
        \WP_CLI::log( "Hello from my command" );
    }
}

if ( defined( 'WP_CLI' ) && WP_CLI ) {
    \WP_CLI::add_command( 'wcb my-thing', My_Command::class );
}

The base class gives you --dry-run, --verbose, structured output (--format=json|table|csv), and the abilities-aware permission helper.

Extension Cookbook

Common things developers ask "how do I…" - with the smallest working snippet for each. Every recipe uses public hooks; nothing here forks the source.

Add a field to the apply form

You want candidates to fill in (say) a "LinkedIn URL" when applying.

// 1. Render the input inside the apply panel.
add_action( 'wcb_application_form_fields', function ( $job_id ) {
    ?>
    <label class="wcb-form-label">
        <span><?php esc_html_e( 'LinkedIn URL', 'my-addon' ); ?></span>
        <input type="url" name="my_addon_linkedin" class="wcb-field" />
    </label>
    <?php
});

// 2. Allow the field through the apply endpoint.
add_filter( 'wcb_application_form_fields_groups', function ( $groups, $job_id ) {
    $groups['my_addon'] = array(
        'fields' => array(
            'linkedin' => array( 'type' => 'url', 'sanitize' => 'esc_url_raw' ),
        ),
    );
    return $groups;
}, 10, 2 );

// 3. Read the saved value later - it's stored as `_wcb_application_field_linkedin`.
$url = get_post_meta( $app_id, '_wcb_application_field_linkedin', true );

Add a column to the admin applications table

add_filter( 'manage_wcb_application_posts_columns', function ( $cols ) {
    $cols['my_score'] = __( 'Score', 'my-addon' );
    return $cols;
});

add_action( 'manage_wcb_application_posts_custom_column', function ( $col, $post_id ) {
    if ( 'my_score' === $col ) {
        echo (int) get_post_meta( $post_id, '_my_score', true );
    }
}, 10, 2 );

Notify Slack when a job is posted

add_action( 'wcb_job_created', function ( $job_id, $request ) {
    $title = get_the_title( $job_id );
    wp_remote_post( SLACK_WEBHOOK_URL, array(
        'body' => wp_json_encode( array(
            'text' => sprintf( '🆕 New job posted: *%s*', $title ),
        ) ),
        'headers' => array( 'Content-Type' => 'application/json' ),
        'blocking' => false,
    ));
}, 10, 2 );

Add a tab to the Settings page

add_filter( 'wcb_settings_tabs', function ( $tabs ) {
    $tabs['my_addon'] = __( 'My Addon', 'my-addon' );
    return $tabs;
});

add_action( 'wcb_settings_tab_my_addon', function () {
    settings_fields( 'my_addon_group' );
    do_settings_sections( 'my_addon_group' );
    submit_button();
});

Override the credit cost for a specific board

add_filter( 'wcb_board_credit_cost', function ( $cost, $board_id ) {
    if ( get_option( 'my_addon_premium_board' ) === $board_id ) {
        return 5; // Override the normal cost
    }
    return $cost;
}, 10, 2 );

Inject a step into the post-a-job wizard

The 4-step wizard fires wcb_job_form_step1_fieldswcb_job_form_step4_preview actions inside each step's container. Adding a fifth step takes a JS-side hook too - but injecting fields into an existing step is trivial:

add_action( 'wcb_job_form_step3_fields', function () {
    ?>
    <div class="wcb-form-field">
        <label class="wcb-form-label">
            <?php esc_html_e( 'Industry sub-category', 'my-addon' ); ?>
        </label>
        <select name="my_addon_subcat">
            <option value="frontend">Frontend</option>
            <option value="backend">Backend</option>
        </select>
    </div>
    <?php
});

Add a column to the REST jobs response

add_filter( 'wcb_rest_prepare_job', function ( $row, $post, $request, $context ) {
    $row['my_remote_friendly'] = (bool) get_post_meta( $post->ID, '_remote_friendly', true );
    return $row;
}, 10, 4 );

This propagates everywhere the jobs API is consumed - the listings block, the single-job page, third-party integrations.

Disable a built-in feature

Most Pro features are gated by wcb_pro_*_enabled filters. To turn off resume builder for a specific role:

add_filter( 'wcb_pro_resumes_enabled', function ( $enabled ) {
    if ( current_user_can( 'wcb_employer' ) ) {
        return false; // Hide resume tab from employers
    }
    return $enabled;
});

Customize the "Buy Credits" link

Different gateways for different user segments:

add_filter( 'wcb_credit_purchase_url', function ( $url ) {
    if ( current_user_can( 'wcb_employer_premium' ) ) {
        return '/premium-credits/';
    }
    return $url;
});

Restrict the boards dropdown by user role

add_filter( 'wcb_board_options_for_employer', function ( $options, $user_id ) {
    if ( ! user_can( $user_id, 'wcb_post_to_premium_boards' ) ) {
        // Drop any board whose id is in the "premium" list.
        $premium_ids = (array) get_option( 'my_premium_board_ids', array() );
        $options = array_filter( $options, fn( $o ) => ! in_array( (int) $o['id'], $premium_ids, true ) );
    }
    return $options;
}, 10, 2 );

(Pro's BP-groups integration uses this same filter to drop boards whose linked BuddyPress group the user is not a member of.)

Add a custom transactional email

add_filter( 'wcb_registered_emails', function ( $emails ) {
    $emails['my_addon_welcome'] = array(
        'subject' => __( 'Welcome to the board', 'my-addon' ),
        'body'    => __( 'Hi {{name}}, welcome to our job board!', 'my-addon' ),
        'context' => 'candidate',
    );
    return $emails;
});

// Fire it from your code:
do_action( 'wcb_send_email', 'my_addon_welcome', $candidate_id, array(
    'name' => $candidate_name,
));

Where to find the rest

Read 02-hooks-reference.md for the full inventory. For anything not covered by a hook, the next step is to extend a Career Board class directly - see 03-rest-api.md for the REST controller base class and the WP-CLI section in 04-wp-cli.md for the CLI base class.

Something unclear? Open a support ticket →

Buy WP Career Board