Wbcom Designs WP Career Board Pro Docs
Back to product Buy Now

Getting Started

Install, license, and activate WP Career Board Pro.

Introduction to WP Career Board Pro

WP Career Board Pro extends the free WP Career Board plugin with powerful features for growing job boards that need more than the basics.

WP Career Board Pro - Feature Overview

What You Get with Pro

Resume Builder

Candidates build structured, multi-section resumes directly on your site. Employers can view formatted resumes linked to each application. → Learn more

Custom Field Builder

Add any custom field to jobs, companies, or candidate profiles - no code required. Text fields, dropdowns, checkboxes, date pickers, file uploads. → Learn more

Application Pipeline (ATS)

Replace the simple 3-status application flow with a full stage pipeline: Screening, Interview, Offer, Hired/Rejected. Track candidates through custom stages with a visual Kanban board. → Learn more

Credit System + Stripe

Charge employers credits to post jobs. Sell credit packages via Stripe Checkout. Set different credit costs per job type or board. → Learn more

Multi-Board Engine

Run multiple independent job boards from one WordPress install. Each board has its own jobs, employers, and settings. A Board Switcher block lets visitors tab between boards. → Learn more

Job Alerts

Candidates subscribe to saved searches and receive email digests when new matching jobs are posted. Frequency controls (daily, weekly, instant) per alert. → Learn more

Job Map

Display job locations on an interactive map alongside your listings. Syncs with the search/filter state - filtering jobs also filters the map pins. → Learn more

AI Chat Search

Natural language job search powered by semantic AI. Candidates type a query like "remote React job with good work-life balance" and get semantically matched results.

Find Resumes (Candidate Archive)

A public-facing resume archive block. Employers and admins can browse publicly listed candidate profiles filtered by skills, location, and job title.

Pro Blocks Reference

WP Career Board Pro adds 15 blocks to the WordPress block inserter on top of the blocks included in the free plugin. → Full block reference

Requirement: Free Plugin

WP Career Board Pro requires the free WP Career Board plugin to be installed and active. Pro adds modules on top of Free - it does not work standalone.

If you haven't installed the free plugin yet, start here.

Licensing

WP Career Board Pro is sold with an annual license. License tiers:

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

Your license includes updates and support for the license period. Renew to continue receiving updates.

Installing WP Career Board Pro

WP Career Board Pro is an add-on plugin. It requires WP Career Board (free) to be installed and activated first.

Prerequisites

Before installing Pro:

  1. ✅ WP Career Board (free) is installed and activated
  2. ✅ WordPress 6.9 or higher
  3. ✅ PHP 8.1 or higher
  4. ✅ You have a valid Pro license from wbcomdesigns.com

Installation Steps

  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 file and click Install Now
  6. Click Activate Plugin

Pro Plugin Upload

What Happens on Activation

On activation, WP Career Board Pro:

  • Checks that WP Career Board (free) is active - if not, activation is blocked with an error message
  • Creates the additional Pro database tables (wcb_credit_ledger, wcb_field_groups, wcb_field_definitions, wcb_field_values, wcb_job_boards, wcb_job_alerts, wcb_application_stages, wcb_ai_vectors, wcb_notifications)
  • Registers all 15 Pro blocks in the block editor
  • Adds Pro settings tabs to WP Career Board → Settings

After Activation

You will see a notice asking you to activate your license. See License Activation for the next step.

Troubleshooting Installation

"WP Career Board (Free) must be installed and active" Install and activate the free plugin first, then retry Pro activation.

"License could not be verified" Make sure your site can make outbound HTTP requests. Check with your hosting provider if firewalled.

Pro tabs not appearing in Settings Deactivate and reactivate Pro. If the issue persists, check WP Career Board → Settings → System Status for errors.

License Activation

Activating your license connects WP Career Board Pro to wbcomdesigns.com for updates and support.

Where to Find Your License Key

  1. Log in to your account at wbcomdesigns.com
  2. Go to My Account → Licenses
  3. Copy the license key for WP Career Board Pro

Primary Method: Pro Setup Wizard

After activating the Pro plugin, a notice appears on all WP Career Board admin screens:

"WP Career Board Pro needs setup - configure your license and credits."

Click Complete Pro Setup to open the Pro Setup Wizard. The wizard walks you through:

  1. License step - paste your license key and click Activate & Continue
  2. Credits Setup step - configure your low-credit threshold and purchase URL
  3. Pro Pages step (mini-wizard only) - creates the Find Candidates page if missing

The wizard is the recommended activation path, especially on new installs.

Alternative: Settings Page

You can also activate the license directly without the wizard:

  1. In your WordPress admin, go to WP Career Board → Settings → License
  2. Paste your license key in the License Key field
  3. Click Activate License

License Settings - Activate

A confirmation message shows your license status, expiry date, and how many sites are active on 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 activated on this site
Invalid Key does not match any license in our system
No activations left All license sites are used - deactivate from another site first

Managing Sites on Your License

To add your license to another site, deactivate it from the current site first:

  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 Your License

When your license expires, WP Career Board Pro continues to work - you just won't receive plugin updates. To renew:

  1. Log in to wbcomdesigns.com
  2. Go to My Account → Licenses
  3. Click Renew next to WP Career Board Pro

After renewal, the plugin automatically picks up the new expiry date on the next license check.

Updates Without an Active License

The plugin functions fully without an active license. License activation is only required to:

  • Receive automatic plugin updates
  • Access priority support

What's New in 1.1.0

Released 27 April 2026. This release focuses on three things: deeper BuddyPress integration for community-and-careers sites, more flexibility around credit pricing, and better embedding for page-builder users.

BuddyPress: community-first integration

If your site already runs BuddyPress with Reign or BuddyX Pro, six new integrations light up automatically:

What Where to read
Every BP group gets a "Jobs" tab listing only that group's jobs Group-scoped boards
Job approvals and hires post to the activity stream Activity stream entries
Application status changes appear in the candidate's BP notification bell Candidate notifications
"Open to work" + "Hiring" chips on /members/ Member directory filters
Different credit cost per BP member type / PMPro level / MemberPress membership Tiered credit pricing
BP group admins can approve/reject jobs on their group's board Group-scoped moderation

Quick Resume Form (single-page)

The new Quick Resume Form captures the essentials - headline, summary, top skills, location, open-to-work, photo - on one screen. Drop it into signup flows, modals over job listings, partner-site embeds, or sidebars. Sibling of the multi-section Resume Builder, not a replacement - both share the same custom-field hook so adding a field once covers both surfaces.

Featured-upgrade credit consumer

Employers can now spend credits to upgrade an existing job to Featured - separate from the cost of posting in the first place. Pairs with Free's new daily cron that auto-clears the featured boost after a configurable duration, so the same job can pay for featured status more than once over its life. See Featured-upgrade consumer.

Page-builder shortcodes

Pro now registers four shortcodes for sites running classic editor, Elementor, Divi, Bricks, or Beaver Builder:

  • [wcbp_resume_form_simple]
  • [wcbp_resume_archive]
  • [wcbp_credit_balance]
  • [wcbp_job_alerts]

Each forwards attributes 1:1 to the underlying block - same casting rules as Free's shortcodes. Full reference: Pro Shortcodes.

Theme parity polish

Pro CSS now uses Free's expanded design-token registry - status colour quintets, transition timings, avatar size scale, theme-aware primary tints. If Reign or BuddyX Pro overrides --wcb-primary, every Pro block restyles automatically. No Pro-specific token file to maintain.

For developers

  • New wcb_resume_form_fields filter family (mirror of Free's wcb_job_form_fields)
  • New wcbp_consumer_cost filter on both credit consumers (job_post + featured_upgrade)
  • New wcb_moderate_jobs_ability_check filter (Free) - Pro hooks it for group-scoped moderation
  • Job map block reads the new {jobs, total, pages, has_more} envelope shape from /wcb/v1/jobs (with Array.isArray() fallback for sites still on Free 1.0.x during the upgrade window)

Full reference: Pro Hooks and Pro Shortcodes.

Credit System

WooCommerce, PMPro, MemberPress, and Stripe credit packages for employers.

Credit System - Overview

The Credit System lets you charge employers credits to post jobs on your board. You sell credit packages, employers buy credits, and credits are deducted when they post a job.

Credit System - Employer Dashboard Credits

How It Works

  1. Admin sets prices - configure how many credits a job post costs (per-board) and what featured-upgrades cost.
  2. Admin creates packages - define bundles of credits to sell, mapped to a WooCommerce product, PMPro level, or MemberPress membership.
  3. Employer buys credits - pays via the configured adapter (WooCommerce checkout, PMPro signup, or MemberPress membership purchase). No Stripe-specific lock-in.
  4. Credits are held on post - when the employer submits a job, the required credits are held.
  5. Credits are deducted - when the job goes live (after approval), credits are deducted from the employer's balance.
  6. Refund on rejection - if a job is rejected by the admin, held credits are released back to the employer.

Setup is a two-step pair {#purchase-url-and-mapping}

The Buy Credits button on the Credit Balance block only renders when both halves of the setup are in place at the same time:

  1. A Credits Purchase URL pointing at the WooCommerce product / PMPro level / MemberPress membership.
  2. At least one Credit Mapping entry mapping that purchase target to a positive credit amount.

If only one half is set - typically a Purchase URL with no mapping - an employer who completes the order would receive zero credits because the adapter has no record of what to top up. To prevent that, the Buy Credits button stays hidden until both halves match, and the Credits admin tab shows a yellow banner pointing at the missing half (1.2.0+):

Credits admin warning when mapping is missing

Add a mapping in the Credit Mappings section below the warning to unblock the button. Removing the Purchase URL clears the warning too (and hides the Buy Credits button entirely until the URL is set again).

Two consumers (1.1.0)

Pro registers two distinct credit consumers - each can charge different amounts for different actions:

Consumer What it covers Cost source
job_post Posting a new job to a board Per-board credit_cost setting (filtered through wcbp_consumer_cost)
featured_upgrade Upgrading an existing job to Featured wcbp_featured_upgrade_cost option (default 10), filtered through wcbp_consumer_cost

Both consumers run their cost callback through the tiered pricing matrix so paid-membership levels can post for less (or for free).

Wbcom Credits SDK

The credit system is built on the Wbcom Credits SDK - a shared library bundled inside WP Career Board Pro. The SDK provides the ledger, balance calculations, and adapter integrations. You do not need to install the SDK separately.

Credit Ledger

Every credit transaction is logged in an append-only ledger. This means:

  • You always have a full audit trail
  • No credit entry is ever edited or deleted
  • Balance is calculated as the sum of all transactions

Transaction types:

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

Employer Experience

Employers see their credit balance in the Employer Dashboard header. When they submit a job and don't have enough credits, they are prompted to purchase a package - the purchase flow runs through whichever adapter you've configured (WooCommerce, PMPro, MemberPress) without sending the employer to a third-party portal.

The same balance + recent-history widget can be embedded on any page using the new [wcbp_credit_balance] shortcode (#shortcodes-reference-wcbp)).

Free Job Posts

Setting the job post cost to 0 credits makes job posting free. The credit system is active but no credits are consumed, so employers don't need to buy anything. Use this to offer free job posting with the infrastructure in place to monetize later.

Where to Next

Stripe Setup

WP Career Board Pro uses Stripe Checkout to process credit package purchases. Setting up Stripe takes about 10 minutes.

Prerequisites

  • A Stripe account (stripe.com)
  • Your Stripe Publishable Key and Secret Key
  • Your site must be on HTTPS (required by Stripe)

Getting Your Stripe Keys

  1. Log in to your Stripe Dashboard
  2. Go to Developers → API Keys
  3. Copy your Publishable key and Secret key

For testing, use the Test mode keys before switching to live.

Configuring Stripe in WP Career Board Pro

  1. Go to WP Career Board → Settings → Credits (Pro tab)
  2. Paste your Publishable Key
  3. Paste your Secret Key
  4. Click Save Changes

Credits Settings - Stripe Keys

Stripe Webhook

Stripe sends a webhook to your site when a payment completes. This is how WP Career Board Pro adds credits to the employer's account after a successful purchase.

Setting Up the Webhook

  1. In your Stripe Dashboard, go to Developers → Webhooks
  2. Click Add Endpoint
  3. Enter your webhook URL:
    https://yourdomain.com/wp-json/wcb/v1/stripe/webhook
    
  4. Select these events to listen for:
    • checkout.session.completed
    • payment_intent.succeeded
    • payment_intent.payment_failed
  5. Click Add Endpoint
  6. Copy the Webhook Signing Secret
  7. Paste it into WP Career Board → Settings → Credits → Webhook Secret

Stripe Webhook Setup

Testing Payments

Use Stripe test mode to verify everything works before going live:

  1. Make sure your keys are the test mode keys (start with pk_test_ and sk_test_)
  2. Use Stripe's test card: 4242 4242 4242 4242, any future expiry, any CVC
  3. Complete a test purchase in your employer dashboard
  4. Verify credits were added to the employer's balance

Switching to Live Mode

When ready to accept real payments:

  1. Replace the test keys with your live mode keys
  2. Update the webhook endpoint to use the live webhook signing secret
  3. Test one real purchase to confirm

Note: Keep test and live Stripe accounts separate. Never mix test keys with live keys.

Credit Packages

Credit packages are the bundles of credits that employers purchase. You define the packages - the quantity, price, and any labels.

Creating a Credit Package

  1. Go to WP Career Board → Credit Packages in wp-admin
  2. Click Add New
  3. Fill in:
Field Description
Package Name The name shown to employers (e.g., "Starter Pack")
Credits Included How many credits this package provides
Price The price in your default currency
Description Optional short description (e.g., "Best for small businesses")
Featured Toggle on to highlight this package in the purchase flow
  1. Click Publish

Credit Packages - Add New

Example Package Structure

A typical tiered structure:

Package Credits Price Per-Credit Cost
Starter 3 credits $29 $9.67
Growth 10 credits $79 $7.90
Agency 25 credits $149 $5.96

Bulk packages offer better value, which encourages larger purchases.

Setting Job Post Cost

Set how many credits it costs to post a single job:

  1. Go to WP Career Board → Settings → Credits
  2. Set the Credits per Job Post value
  3. Click Save Changes

You can set different costs based on job type (featured jobs cost more, for example) - contact support for advanced pricing rules.

Free Job Posting

To offer free job posting, set Credits per Job Post to 0. The credit system stays active (so you can switch to paid later), but no credits are consumed on submission.

Employer Credit Balance

Employers see their current credit balance in:

  • The Employer Dashboard header
  • The Confirm & Submit step of the Job Form (before submitting)

When balance is too low to post a job, employers see a "Buy Credits" prompt with your available packages.

Granting Credits Manually

Admins can add credits to any employer's account manually:

  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 and a note
  4. Click Add Credits

This is useful for compensating employers after a rejected job, offering trial credits, or fixing payment issues.

Viewing the Credit Ledger

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

Selling Credits Through WooCommerce

This is the most common credit-purchase setup. WooCommerce handles payment processing (with its own Stripe, PayPal, Square, or any other WC gateway), and WP Career Board Pro listens for completed orders and credits the employer's balance automatically.

Use this guide when:

  • You already have a WooCommerce store on your site.
  • You want employers to buy credit packs the same way they would buy any other product (cart, checkout, account orders page).
  • You want to sell recurring credits (e.g. "10 credits per month") - that uses WooCommerce Subscriptions, covered below.

Prerequisites

  • WooCommerce is installed and active.
  • (Optional) WooCommerce Subscriptions is installed if you want recurring credit packs.
  • At least one WooCommerce payment gateway is configured (WooCommerce → Settings → Payments).
  • The Career Board Credit System is enabled (Career Board → Settings → Credits → "Enable credits").

Step 1: Create a Credit Product in WooCommerce

  1. Go to Products → Add New.
  2. Set the product name (e.g. "10 Job Posting Credits").
  3. Set the product Price.
  4. Under Product Data, leave the type as Simple product (or Simple subscription for recurring credits).
  5. Optionally mark the product Virtual - credits aren't shipped.
  6. Publish the product.

Step 2: Map the Product to a Credit Amount

  1. Go to Career Board → Settings → Credits.
  2. In the Credit Mappings section, click Add mapping.
  3. Pick WooCommerce as the adapter.
  4. Choose the product you just created.
  5. Enter the number of credits (e.g. 10).
  6. Click Save Changes.

Repeat for as many credit packs as you want to offer (10, 50, 100, …).

Step 3: Set the "Buy Credits" Page URL

When an employer is low on credits, the dashboard shows a Buy Credits button. Point that button at your WooCommerce shop:

  1. Career Board → Settings → Credits → Credit Purchase URL.
  2. Set it to the URL of either:
    • A single product page (e.g. /product/10-job-posting-credits/)
    • A category page that lists every credit pack
    • A custom "Buy Credits" page you've built with a product grid
  3. Save Changes.

Leave it empty if you don't want the "Buy Credits" button to appear.

Step 4: Test the Flow

  1. Log in as an employer (or use a test account).
  2. Go to Career Board → Employer Dashboard.
  3. Note the current credit balance.
  4. Click Buy Credits, complete the WooCommerce checkout.
  5. Once the order status moves to Completed, return to the dashboard.
  6. The balance updates automatically - the credit-purchase row appears in the credit ledger with type: topup.

Recurring Credits With WooCommerce Subscriptions

If you want monthly credit packs (e.g. "20 credits/month"):

  1. Install WooCommerce Subscriptions.
  2. Create the product as a Simple subscription.
  3. Map it the same way under Credit Mappings → Adapter: WooCommerce Subscriptions.
  4. Set the credit amount that gets added on every successful renewal.

When the subscription renews, the same topup ledger entry is written - same flow, just on a schedule.

How It Looks in the Ledger

Every credit transaction is recorded in an append-only ledger. Going to Career Board → Reports → Credit Ledger shows each employer's history:

Type Trigger Notes
topup WooCommerce order completed Includes the order ID, product ID, credit amount
hold Employer submitted a job Reserves the cost; awaiting approval
deduct Job approved + published Final consumption
refund Job rejected by admin Returns the held credits

The ledger is the source of truth - even if a customer disputes later, you can prove exactly what happened.

Troubleshooting

Order completed but credits didn't add. Check Career Board → Settings → Credits → Status. The page shows whether the WooCommerce adapter is registered. If it says "WooCommerce not detected" but Woo is active, reinstall the plugin or deactivate/reactivate Career Board Pro to re-trigger registration.

Credits added twice for the same order. The ledger is idempotent on order ID - duplicate webhook deliveries do not double-credit. If you genuinely see two topup rows for the same order, file a bug - that's a real failure mode and we want to catch it.

Employer bought credits before the product was mapped. The order won't credit them automatically. Use Manual Adjustments (see 08-manual-adjustments-and-refunds.md) to add the credits by hand.

Related

Granting Credits via Paid Memberships Pro

Use this when you want employers to subscribe to a membership level that includes job-posting credits - instead of buying credit packs one at a time.

Use this guide when:

  • You already use Paid Memberships Pro to gate access on your site.
  • You want a "Gold tier: 100 credits/month, Silver tier: 25/month" pricing structure.
  • You want to grant credits automatically on a membership level upgrade (or take them away on downgrade).

Prerequisites

  • Paid Memberships Pro is installed and active.
  • You've created at least one Membership Level (PMPro → Membership Levels).
  • Career Board Credit System is enabled (Career Board → Settings → Credits → "Enable credits").

Step 1: Map a Level to a Credit Amount

  1. Go to Career Board → Settings → Credits.
  2. Under Credit Mappings, click Add mapping.
  3. Pick Paid Memberships Pro as the adapter.
  4. Choose the membership level (e.g. "Employer Gold").
  5. Enter the credit amount granted on every renewal (e.g. 100).
  6. Save Changes.

Repeat for each tier you want to offer.

Step 2: How the Grant Works

  • On first checkout - when a member completes payment for a level, the mapped credit amount is added immediately (one topup ledger row).
  • On renewal - for recurring levels, every renewal adds the same credits (a fresh topup row each cycle). Credits do NOT roll over by default - see "Rolling vs Resetting" below.
  • On cancellation / expiry - no automatic deduction. The member keeps whatever balance they had. If you want to reset balances on expiry, use the wcbp_credit_revoke_on_level_expire filter (see the developer guide).

Step 3: Test the Flow

  1. Go to PMPro → Membership Levels → choose your mapped level → Test Checkout.
  2. Use a test card (or a free level with a temporary discount code).
  3. Complete the checkout.
  4. As that test user, visit Career Board → Employer Dashboard.
  5. The credit balance shows the mapped amount.
  6. Career Board → Reports → Credit Ledger shows a topup row with source: pmpro, level_id: <your level ID>.

Rolling vs Resetting Credits

By default credits accumulate - if Gold gives 100/month and the employer doesn't post any jobs, after 3 months they have 300 credits.

If you want each renewal to reset to the level's allotment instead:

  1. Career Board → Settings → Credits.
  2. Tick "Reset balance on membership renewal".
  3. Save Changes.

When this is on, the renewal flow first writes a deduct row for any leftover balance, then a topup for the new allotment.

Common Patterns

Free trial: 5 credits, then 100/month on upgrade.

  1. Create a "Free Trial" PMPro level (price $0).
  2. Map it to 5 credits.
  3. Create your paid level ("Employer Gold").
  4. Map it to 100 credits.

When the trial member upgrades, they get 5 + 100 = 105 (no reset). Tick "Reset balance on membership renewal" if you'd rather they get only 100 on upgrade.

Annual plans.

PMPro supports annual recurring levels - Career Board's adapter listens for the renewal event regardless of cycle length, so the mapping works the same way for monthly or yearly plans.

Discount codes that grant bonus credits.

Use the wcbp_credit_pmpro_bonus filter to add a one-time bonus when a specific discount code is redeemed. See the developer guide.

Troubleshooting

Member subscribed but no credits added. Career Board → Settings → Credits → Status. The page shows whether the PMPro adapter is registered. If "PMPro not detected", deactivate and reactivate Career Board Pro.

Test transactions don't add credits. Career Board's adapter only acts on the pmpro_after_change_membership_level hook. Test mode that doesn't fire that hook (e.g. preview-mode in Stripe Sandbox without a real webhook delivery) won't trigger credits. Use PMPro's "Test Checkout" link instead.

Renewal didn't add credits. PMPro fires pmpro_subscription_payment_received on successful renewals - check that hook is firing by enabling PMPro → Memberships → Reports → Subscription Renewals. If the renewal isn't logged in PMPro, the credit grant won't fire either.

Related

Granting Credits via MemberPress

The MemberPress adapter works the same way as PMPro - a member buys a membership product, the membership grants a credit amount, every renewal tops up again.

Use this guide when:

  • You use MemberPress to manage members and access rules.
  • You want tiered credit allotments based on membership level.
  • You want recurring credit grants tied to MemberPress renewals.

Prerequisites

  • MemberPress is installed and active.
  • You've created at least one Membership (MemberPress → Memberships).
  • Career Board Credit System is enabled.

Step 1: Map a Membership to Credits

  1. Go to Career Board → Settings → Credits.
  2. Under Credit Mappings, click Add mapping.
  3. Pick MemberPress as the adapter.
  4. Choose the Membership (e.g. "Employer Premium").
  5. Enter the credit amount granted per cycle (e.g. 50).
  6. Save Changes.

Step 2: How the Grant Works

  • On signup - mepr-event-transaction-completed fires; the adapter writes a topup ledger row for the mapped amount.
  • On renewal - same event fires for recurring memberships; another topup row each cycle.
  • On cancellation / expiry - no automatic deduction. Member keeps the balance they had. Use wcbp_credit_revoke_on_member_expire filter to change this.
  • On manual transaction creation (via MemberPress admin) - same event fires, same grant happens.

Step 3: Test the Flow

  1. MemberPress → Memberships → choose your mapped membership.
  2. Use the Membership URL to subscribe with a test account.
  3. Complete checkout.
  4. As that member, visit Career Board → Employer Dashboard.
  5. Confirm the balance shows the mapped amount.
  6. Career Board → Reports → Credit Ledger shows topup with source: memberpress, membership_id: <your ID>.

Common Patterns

Trial + paid combination.

Create two memberships: "Trial (free, 5 credits, 7 days)" and "Premium (paid recurring, 50 credits/month)". Map each. MemberPress handles the transition; the adapter responds to whichever transaction event fires.

One-time membership = one-time credit grant.

Map a non-recurring membership to a credit amount. Member buys once, gets the credits once. They keep the credits indefinitely; they just don't get more without buying again.

Membership rules tied to credit balance.

MemberPress can restrict access based on user meta. The credit balance is stored in wcb_credit_ledger (computed) and surfaced via get_user_meta($user_id, '_wcb_credit_balance', true) if you've enabled the cache. Use that for MemberPress access rules - e.g. "only let members with ≥10 credits see the Premium Job Board page."

Troubleshooting

Member completed checkout but no credits. Career Board → Settings → Credits → Status will say "MemberPress detected" if the adapter is wired correctly. If not, reactivate Career Board Pro after MemberPress is installed.

Webhook-based payment didn't credit. MemberPress fires mepr-event-transaction-completed only after the payment gateway confirms. If you're using Stripe / PayPal in MemberPress's webhook mode and the webhook hasn't reached your site (check MemberPress → Reports → Transactions for "Pending"), no credits fire. Investigate the gateway webhook first.

Related

Manual Credit Adjustments & Refunds

Sometimes the automatic flow doesn't fire - a payment processor glitches, an order was placed before you mapped the product, a customer needs a comp credit for a complaint. The Manual Adjustments panel is where admins do that.

Use this guide when:

  • You need to grant credits manually (comp, refund, promotional, support gesture).
  • You need to deduct credits manually (charge for an off-platform service).
  • You need to refund credits that were charged for a job that ended up rejected, deleted, or disputed.
  • You need to audit a customer's credit history to investigate a complaint.

Where to Find the Panel

Career Board → Reports → Credit Ledger.

Each employer's row has a Adjust button. Clicking it opens a modal where you can add or remove credits with a reason.

You can also reach it from the user's profile: Users → All Users → edit a user → Career Board → Credit balance.

Granting Credits

  1. Open the Credit Ledger.
  2. Find the employer (search by name, email, or user ID).
  3. Click Adjust.
  4. Set Type to "Grant credits".
  5. Enter the Amount (e.g. 25).
  6. Enter a Reason (e.g. "Comp for incident #4892 - apply email bug", "Beta tester thank-you", "Migration grant from Job Manager").
  7. Click Apply.

A topup row is written to the ledger with source: manual, actor: <your admin user ID>, and the reason you entered. The employer's balance updates immediately.

Deducting Credits

  1. Same panel, but set Type to "Deduct credits".
  2. Enter the amount you want to remove.
  3. Enter a reason (e.g. "Refund - credit pack chargeback on order #1234", "Adjustment - duplicate auto-grant").
  4. Apply.

A deduct row appears with source: manual. The balance can't go below zero - if the adjustment would take it negative, the operation is rejected and you'll see an error.

To override that (rare, e.g. recouping a balance from a comped employer who never paid), use the Allow negative balance checkbox in the same modal.

Refunding a Specific Job's Credits

If an employer paid credits for a job that turned out to be a duplicate, spam, or the wrong listing, you can refund those exact credits without touching their other history:

  1. Open the job's edit page (Career Board → Jobs → edit).
  2. Scroll to Credit transaction in the sidebar.
  3. Click Refund credits to employer.
  4. Confirm.

A refund row appears in the ledger referencing the job's _wcb_job_id. The employer's balance increases by the amount that was charged when the job was originally approved.

You can't refund a job that's still in hold status - those credits haven't been deducted yet, so there's nothing to refund. Just reject the job instead, and the held credits return automatically.

Audit Trail

Every manual action - grant, deduct, refund - writes a row to the ledger with:

Field Value
actor_id The admin who made the adjustment
actor_login Their WP user login
source manual
reason The text you entered
at ISO timestamp (UTC)

This is append-only - manual rows can't be edited or deleted. If you made a mistake, write a reversing entry with a clear reason ("Reversing earlier comp - was applied to the wrong account").

Refunding External Payments

If a customer chargebacks their credit-pack purchase through their bank or via the payment gateway, you should:

  1. Confirm the chargeback in WooCommerce / PMPro / MemberPress first - the gateway's record is authoritative.
  2. Deduct the credits manually using the steps above, with the reason "Chargeback on order #X / transaction #Y".
  3. Optionally suspend the user if the chargeback was fraudulent (Users → set role to wcb_employer_banned).

Career Board does NOT automatically deduct credits when a WooCommerce order is refunded - that's intentional, because some refunds are goodwill gestures where you want the customer to keep the credits. Always make the deduction explicit.

Bulk Adjustments

Use the WP-CLI command for bulk grants (e.g. "give every employer who registered before 2026-01-01 a 50-credit migration grant"):

wp wcb credits grant --user_ids=12,15,17,22 --amount=50 --reason="Migration grant from BPJM"

See the developer guide for the full WP-CLI reference once it ships.

Troubleshooting

"Adjust" button is greyed out. You don't have the wcb_manage_settings capability. Site administrators have it by default; other roles need it granted explicitly via your user-role manager.

Adjustment applied but balance didn't update on dashboard. The employer dashboard caches the balance for 5 minutes. Either wait, or have the employer log out and back in to refresh.

I deducted credits, customer disputes the deduction. The audit trail is your record. Show them the ledger row with your reason and timestamp. If you genuinely made an error, write a reversing topup row - never edit or delete the original entry.

Related

Application Pipeline

Kanban-style ATS pipeline with configurable hiring stages.

Application Pipeline - Overview

The Application Pipeline replaces the free version's simple three-status system (Submitted / Reviewed / Closed) with a fully customizable ATS-style stage workflow.

Application Pipeline - Kanban Board

What You Get

  • Custom stages - define as many stages as your hiring process needs (e.g., Screening, Phone Interview, Technical Test, Final Interview, Offer, Hired)
  • Kanban board view - drag and drop applicant cards between stages
  • Terminal stages - mark stages as terminal with an outcome of "Hired" or "Rejected" - this automatically closes the application
  • Per-board configuration - each job board can have its own stage set (Pro multi-board feature)
  • Stage history - every stage change is logged with a timestamp

How It Compares to the Free Version

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

Default Stages

When you first enable the Pipeline, the following default stages are created:

  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.

Where to Next

Configuring Pipeline Stages

Accessing the Pipeline Settings

Go to WP Career Board → Settings → Pipeline (Pro tab).

You will see the stage list for your job board with drag-to-reorder handles.

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

The new stage appears in the list in the order you placed it.

Stage Colors

Each stage gets a colored badge in the Kanban view and the application list. Choose colors that give instant visual meaning:

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

Terminal Stages

A terminal stage ends the hiring process for an applicant. When you move a candidate to a terminal stage:

  • Their core 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 that notification is enabled)

You must have at least one terminal stage with the "Hired" outcome and one with the "Rejected" outcome.

Reordering Stages

Drag and drop any stage row to change its position in the pipeline. The order determines how stages appear in the Kanban columns (left to right).

Deleting a Stage

Click Delete on any stage. If applications are currently in that stage, you will be asked to select a stage to move those applications to before deletion.

Using the Kanban Board

To access the Kanban board:

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

Each column represents a stage. Drag and drop applicant cards between columns to move candidates through the pipeline.

Click any candidate card to open their full application details.

Bulk Moving Candidates

Select multiple candidates using the checkboxes in list view, then use the Move to Stage dropdown to move all selected candidates at once.

Field Builder

Add custom fields to jobs, candidates, and applications.

Custom Field Builder - Overview

The Field Builder lets you add any custom fields to jobs, companies, and candidate profiles - without writing any code.

Field Builder - Admin Interface

What You Can Do

  • Add fields to job listings (e.g., Remote Policy, Visa Sponsorship, Tech Stack)
  • Add fields to company profiles (e.g., Funding Stage, Glassdoor Rating, Benefits)
  • Add fields to candidate profiles (e.g., Preferred Work Style, Notice Period, Portfolio URL)
  • Group related fields into collapsible sections
  • Set fields as required or optional
  • Control which fields are visible to guests vs registered users

How It Works

Fields created in the Field Builder are:

  1. Shown in the relevant form - job posting form, company profile editor, candidate profile editor
  2. Displayed on the public page - job single page, company profile page, candidate profile
  3. Stored securely - values saved in WP Career Board's dedicated wcb_field_values table

No custom database columns, no custom meta box hacks.

Field Groups

Fields are organized into groups. A group is a collapsible section with a label (e.g., "Compensation", "Requirements"). You can have multiple groups per entity type.

Visibility Rules

Each field can be set to:

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

Where to Next

Creating Custom Fields

Accessing the Field Builder

Go to WP Career Board → 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

Before adding fields, create a group to hold them:

  1. Click Add Group
  2. Enter a group label (e.g., "Compensation Details")
  3. Click Save Group

The group appears as a collapsible section. You can create multiple groups to organize related fields.

Adding a Field to a Group

  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 (for text fields)
Options The choices available (for Select and Checkbox fields)
  1. Click Save Field

Adding a Custom Field

Reordering Fields and Groups

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

Editing and Deleting Fields

  • Click Edit on any field to change its settings
  • Click Delete to permanently remove the field and all stored values

Warning: Deleting a field deletes all data stored in that field across all posts. This cannot be undone.

Where Fields Appear

After saving, fields appear automatically:

  • Job Fields → in the multi-step Job Form (employer posting) and on the job single page
  • Company Fields → in the Company Profile editor and on the public company page
  • Candidate Fields → in the candidate's profile settings (future: in the application form)

Field Types Reference

WP Career Board Pro supports the following field types in the Field Builder.

Text

A single-line text input.

Use for: Short text values - job perks, tech stack keywords, notice period, LinkedIn URL.

Options:

  • Placeholder text
  • Max character length (optional)

Textarea

A multi-line text input.

Use for: Longer descriptions - benefits overview, ideal candidate description, company culture note.

Options:

  • Placeholder text
  • Min/max character length (optional)

Number

A numeric input field.

Use for: Salary ranges, years of experience required, team size.

Options:

  • Min value
  • Max value
  • Step increment

Select (Dropdown)

A single-choice dropdown.

Use for: Remote policy (On-site / Hybrid / Remote), visa sponsorship (Yes / No / Case by case), seniority.

Options:

  • List of choices - enter one option per line
  • Default selected value (optional)

Multi-Select

A dropdown that allows multiple selections.

Use for: Tech stack (JavaScript, Python, Go), required certifications, industry sectors.

Options:

  • List of choices - enter one option per line

Radio Buttons

A group of mutually exclusive radio button options.

Use for: Preference questions where you want all options visible at once rather than in a dropdown.

Options:

  • List of choices - enter one option per line

Checkbox (Single Toggle)

A single on/off checkbox.

Use for: "Actively hiring?", "Visa sponsorship available?", "Open to relocation?"

Date

A date picker input.

Use for: Application deadline (if you want a custom per-job date rather than global expiry), estimated start date.

Date Range

Two date pickers for a start and end date.

Use for: Project duration, contract period, employment gap tracking.

URL

A validated URL input.

Use for: Portfolio link, GitHub, LinkedIn, job application external link.

Video URL

A URL input validated for video links (YouTube, Vimeo, etc.).

Use for: Company culture video, candidate introduction video, job preview clip.

Email

A validated email address input.

Use for: Secondary contact email, recruiter contact, HR inquiry address.

File Upload

Lets users attach a file to a job, company profile, or application.

Use for: Attaching a job description PDF, a company one-pager, a candidate portfolio document.

Options:

  • Allowed file types (PDF, DOC, images, etc.)
  • Max file size

Note: Uploaded files are stored as WordPress media attachments.

Tips for Choosing Field Types

  • Use Select when options are mutually exclusive and the list is short (3-8 items)
  • Use Multi-Select when multiple selections are valid and expected
  • Use Radio when you want all options visible without a dropdown
  • Use Text for anything that doesn't fit a specific type - it's the most flexible
  • Keep required fields to a minimum - every required field reduces form completion rates

Resume Builder

Structured resume builder, single-page form, and resume search.

Resume Builder - Overview

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

Resume Builder - Full View

What Candidates Can Build

A resume in WP Career Board Pro 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, employment type, location, dates, current role flag, description, skills used
School Education School name, certificate, field of study, dates, grade, description
College / University Institution, degree type, field of study, dates, GPA, description, achievements
Skills Skill name and optional proficiency level
Languages Language name and proficiency
Certifications Certificate name, issuing body, issue date, expiry date, credential ID and URL
Portfolio / Links Label (e.g., "GitHub") and URL

Candidates can expand, collapse, and reorder entries within each section.

How Resumes Connect to Applications

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

Multiple Resumes

Candidates can create more than one resume (e.g., one for software roles, one for design roles). The dashboard shows all resumes with their last-updated date.

If a maximum resume limit is set (configurable), candidates will see a usage indicator ("2/3 resumes used").

Resume Visibility

Resumes are private by default - only the candidate and employers who receive applications can view them. A public visibility toggle lets candidates make their resume discoverable in a candidate directory (a Pro feature for future release).

Where to Next

Setting Up the Resume Builder

The Resume Builder is delivered as a Gutenberg block. You need to create a dedicated page and add the block to it.

Step 1: Create the Resume Builder Page

  1. Go to Pages → Add New
  2. Set the title (e.g., "Resume Builder" or "Edit Resume")
  3. Add the Resume Builder block to the page body
  4. Publish the page

Adding the Resume Builder Block

Step 2: Register the Page in Settings

  1. Go to WP Career Board → Settings → Pages
  2. Find the Resume Builder Page field
  3. Select the page you just created
  4. Click Save Changes

This setting tells the plugin where to send candidates when they click "Edit Resume" from their dashboard.

Step 3: Link from the Candidate Dashboard

Once the page is assigned in settings, the Candidate Dashboard → My Resumes tab automatically shows:

  • An "Edit" button on each resume that navigates to the Resume Builder page with that resume loaded
  • A "Create New Resume" button (or form, if the inline form is enabled)

No further configuration is needed.

Optional: Embedded vs Standalone Mode

Standalone mode (default): The Resume Builder lives on its own page. Clicking "Edit" navigates to that page with a ?resume_id= query parameter.

Embedded mode: If you add the Resume Builder block on the same page as the Candidate Dashboard, the builder loads inline within the dashboard (without a page change). The block detects the resume_id parameter and loads the correct resume.

To use embedded mode, add the Resume Builder block to your Candidate Dashboard page instead of a separate page.

Configuring the Block

The Resume Builder block has no configurable attributes in the editor - all customization is handled via CSS. See the CSS class reference if you want to adjust the styling.

Resume Builder - Candidate Guide

This guide explains how candidates use the Resume Builder to create and manage their resumes.

Accessing the Resume Builder

From the Candidate Dashboard:

  1. Click the My Resumes tab
  2. Click Create New Resume - enter a title (e.g., "Software Engineer Resume") and click Save
  3. Click Edit on any existing resume

The Resume Builder page opens with your resume loaded.

My Resumes Tab - Dashboard

Creating a New Resume

When you create a resume, you give it a name. This is just for your own reference - the name appears in your dashboard list and is not visible to employers.

The Resume Builder Interface

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

Resume Builder - Open Sections

Professional Summary

The summary is a free-text field at the top of the builder. Write a short 2-4 sentence overview of your background and goals.

Adding Entries (Experience, Education, etc.)

  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 the row to expand and edit it again.

Entry Fields

Work Experience:

  • Job Title (required)
  • Company (required)
  • Employment Type (e.g., Full-time, Contract)
  • Location
  • Start Date / End Date
  • "Currently working here" checkbox (hides End Date)
  • Description
  • Skills Used

School Education:

  • School Name (required)
  • Certificate
  • Field of Study
  • Start Date / End Date
  • Grade
  • Description

College / University:

  • Institution (required)
  • Degree Type (required)
  • Field of Study
  • Start Date / End Date
  • GPA
  • Description
  • Achievements

Skills:

  • Skill name (required)
  • Proficiency level (optional: Beginner, Intermediate, Advanced, Expert)

Languages:

  • Language name (required)
  • Proficiency (e.g., Native, Fluent, Conversational)

Certifications:

  • Certificate name (required)
  • Issuing organization
  • Issue date
  • Expiry date
  • Credential ID
  • Credential URL

Portfolio / Links:

  • URL (required)
  • Label (e.g., "Portfolio", "GitHub")

Removing an Entry

Click Remove on any entry. You will be asked to confirm before it's deleted.

Saving the Resume

The Resume Builder auto-saves each section entry when you click Save on that entry. There is no global save button - each change is saved individually.

A "Saved" confirmation message briefly appears after each save.

Deleting a Resume

  1. Go to Candidate Dashboard → My Resumes
  2. Click the Delete icon on the resume you want to remove
  3. Confirm in the prompt

Deleted resumes are removed permanently.

Visibility Toggle

Each resume has a visibility toggle in the builder header. When set to Private (default), only you and employers you apply to can see it. Public visibility (for a candidate directory) is coming in a future release.

Quick Resume Form (Single-Page)

The Quick Resume Form is a single-page sibling of the multi-section resume builder. New in WP Career Board Pro 1.1.0.

When to use it

Use the Quick Resume Form when you need a candidate to capture a "good-enough-to-apply" profile in 60 seconds:

  • At signup - drop it into the registration confirmation page so candidates land with a usable profile already filled in.
  • In a modal over job listings - when somebody clicks "Apply" but doesn't have a resume yet, surface this form instead of bouncing them to a separate page.
  • In partner-site embeds - embed via shortcode on a partner careers landing page.
  • In your sidebar - the compact attribute makes the layout dense enough for a 320px sidebar.

Keep the multi-section Resume Builder on the dedicated "Edit My Resume" dashboard page for completeness - that's where candidates fill in education, experience, certifications, languages, and portfolio over time.

What it captures

  • Headline (e.g. "Senior Backend Engineer · 8 years · open to remote")
  • Professional summary (rich text, multiline)
  • Top skills (comma-separated chips, drives matching + search facets)
  • Years of experience (dropdown)
  • Location (free text or geocoded)
  • Open-to-work toggle (#member-directory-filters-wcbp))
  • Profile photo (optional - set showPhotoField="false" to hide)

Two ways to embed

Block

Insert Resume Form (Quick Profile) from the block inserter (under Widgets). Configure attributes from the sidebar inspector: showPhotoField, compact.

Shortcode

[wcbp_resume_form_simple]
[wcbp_resume_form_simple compact="true" showPhotoField="false"]

Full attribute reference: Pro Shortcodes.

Customising the fields

The same wcb_resume_form_fields filter that drives the multi-section builder also drives the Quick Resume Form. Add custom fields once, get them on both surfaces:

add_filter( 'wcb_resume_form_fields', function ( $groups ) {
    $groups[] = array(
        'id'     => 'preferences',
        'label'  => __( 'Work preferences', 'my-theme' ),
        'fields' => array(
            array(
                'key'  => '_wcb_preferred_timezone',
                'label' => __( 'Preferred timezone', 'my-theme' ),
                'type' => 'select',
                'options' => array( 'UTC', 'EST', 'PST', 'IST' ),
            ),
        ),
    );
    return $groups;
});

The schema matches Free's wcb_job_form_fields filter - see the Pro Hooks reference for the full field-group format.

Save semantics

Saving the form upserts the candidate's wcb_resume post (creating one on first save). The same fields are reachable from the multi-section builder afterwards - candidates can complete the rest of their profile when they're ready.

There is no "publish" step on this form by design. Quick Resume Form saves keep the resume in whatever public/private state the candidate last set; the candidate flips visibility from the dashboard.

Custom Resume Fields

Add custom fields to the Resume Builder + Quick Resume Form using the same declarative filter pattern as Free's wcb_job_form_fields. A field added once renders on both forms.

The filter

add_filter( 'wcb_resume_form_fields', function( $groups ) {
    $groups[] = [
        'group_id'    => 'links',
        'group_label' => __( 'Online presence', 'wp-career-board-pro' ),
        'fields'      => [
            [
                'key'      => 'github_url',
                'label'    => __( 'GitHub profile', 'wp-career-board-pro' ),
                'type'     => 'url',
                'required' => false,
            ],
            [
                'key'      => 'linkedin_url',
                'label'    => __( 'LinkedIn profile', 'wp-career-board-pro' ),
                'type'     => 'url',
                'required' => false,
            ],
            [
                'key'      => 'website_url',
                'label'    => __( 'Personal website', 'wp-career-board-pro' ),
                'type'     => 'url',
                'required' => false,
            ],
        ],
    ];
    return $groups;
} );

After this filter is in place:

  • The full multi-section Resume Builder renders a new "Online presence" group on the Profile / Links section.
  • The single-page Quick Resume Form renders the same group inline.
  • Values persist as resume postmeta _wcb_resume_field_github_url and so on.
  • The fields appear on the resume single page (under the Links section) and in the resume export PDF.
  • They're exposed in the REST API at GET /wcb/v1/resumes/{id} under the custom_fields.links object.

Field types

Same field types as Free's Custom Fields filter:

text, textarea, email, url, number, select, radio, checkbox, multi-checkbox, date.

Initial state filter

For Interactivity-API-driven forms (Quick Resume Form), the initial state hydrates from a separate filter so you can pre-populate values from a partner site / referral context:

add_filter( 'wcb_resume_form_initial_state', function( $state, $user_id ) {
    // Pre-fill from a partner integration
    $partner_data = get_user_meta( $user_id, '_partner_profile_links', true );
    if ( $partner_data ) {
        $state['custom_fields']['github_url']   = $partner_data['github']   ?? '';
        $state['custom_fields']['linkedin_url'] = $partner_data['linkedin'] ?? '';
    }
    return $state;
}, 10, 2 );

Field Builder admin UI

If you'd rather configure custom fields without writing PHP, install the Field Builder admin page - it writes to the wcb_field_groups / wcb_field_definitions Pro tables and contributes to the wcb_resume_form_fields filter at runtime.

Persistence

Storage Key
Per-field postmeta _wcb_resume_field_<key>
Bundle (one-shot read) _wcb_resume_fields_bundle
REST endpoint GET /wcb/v1/resumes/{id}custom_fields object

Use the per-field meta keys when displaying values on the front-end; use the bundle when importing/exporting resumes in bulk.

Validation

The plugin runs validators that match the field type:

  • url - esc_url_raw() + checks for valid scheme
  • email - is_email() check
  • number - numeric coercion + min/max bounds
  • select / radio - value must be one of the registered option keys
  • multi-checkbox - every value must be in the registered options

Validation failures show inline error messages in the same place a required-field error would.

See also

Single-Page Resume Form (Pro)

WP Career Board Pro 1.1.1 ships three resume form variants so site owners can pick the candidate experience that fits their audience. All three write to the same wcb_resume post type and the same REST endpoint, so candidates can move between variants without losing data.

The three variants

Variant Block Shortcode What it is
Resume Builder (default) wcb/resume-builder [wcbp_resume_builder] Multi-step accordion: each section collapses, entries shown as compact cards with inline edit forms. Best for first-time candidates who want guided section-by-section completion.
Resume Form (Single-Page) wcb/resume-form [wcbp_resume_form] Single-page comprehensive form. Every section expanded on one scrolling page. Best for returning candidates editing an existing resume, partner integrations, sites that prefer a continuous-scroll feel.
Quick Profile wcb/resume-form-simple [wcbp_resume_form_simple] Minimal single-page profile: headline, summary, top skills, location, open-to-work, photo. Best for sidebars, modals, onboarding flows where a full resume is overkill.

All three operate on the resume the URL points at (?resume_id=N), require the resume to belong to the current user, and write to the same PUT /wcb/v1/resumes/{id} endpoint.

When to pick which

Default site: ship wcb/resume-builder on the resume page (the setup wizard does this for you). Candidates get the friendly stepped flow.

Returning-candidate edit page: switch the resume page to wcb/resume-form so candidates see everything at once and can edit freely without expanding accordions.

Onboarding card / sidebar / modal: use wcb/resume-form-simple for a quick-completion experience. Candidates can flesh out the full resume later via the builder.

Sections covered by wcb/resume-form

All seven sections defined by ResumeModule::get_groups():

  1. School - school_name, certificate, field_of_study, start/end dates, grade, description
  2. College / University - institution, degree_type, field_of_study, start/end dates, gpa, description, achievements
  3. Work Experience - company, job_title, employment_type, location, start/end dates, current_role checkbox, description, skills_used
  4. Certifications - cert_name, issuing_body, issue/expiry dates, credential_id, credential_url
  5. Skills - skill_name, proficiency
  6. Languages - language, proficiency
  7. Portfolio / Links - label, url

Each section has an Add [Section] button at the top right. Each entry has a Remove button at the bottom that prompts a confirm dialog before deleting.

Editor inserter

The block appears in the block inserter under the Widgets category. Two attributes:

Attribute Type Effect
compact bool Tighter padding (sidebars, modals, narrow columns). Default off.

Switching the resume page from builder to single-page

  1. Go to Pages → All Pages and find the page that hosts your resume editor (usually titled "My Resume" or similar - created by the Pro setup wizard).
  2. Edit the page in the block editor.
  3. Remove the Resume Builder block.
  4. Insert the Resume Form (Single-Page) block.
  5. Save.

Candidates who already have resume data see the same data - no migration needed. The two blocks share the database.

Compatibility note

The wcbp_resume_groups filter, wcbp_resume_textarea_fields, wcbp_resume_checkbox_fields, and wcbp_resume_date_fields filters apply to all three variants. Add-ons that customise the builder's sections (e.g. to add a "Patents" section or a custom field type) automatically affect the single-page form too.

Where to go next

BuddyPress Integration

Group boards, activity stream, tiered credit pricing, and notifications.

BuddyPress Integration - Overview

WP Career Board Pro is built for community sites running on Reign or BuddyX Pro themes with BuddyPress underneath. Activate BuddyPress and the Pro plugin lights up five integrations automatically - no settings to configure.

Activation: these integrations only register when BuddyPress is active (bp_is_active()). Tiered credit pricing is the one exception

  • it loads outside the BP gate so PMPro / MemberPress sites without BuddyPress still get per-membership pricing.

What you get

Integration What it does
Group-scoped job boards Every BuddyPress group automatically gets a "Jobs" tab listing only that group's jobs.
Activity stream entries Job approvals post to the activity feed; hires post a celebratory entry.
Candidate notifications Application status changes appear in the candidate's BP notification bell.
Member directory filters "Open to work" and "Hiring" chips on /members/.
Tiered credit pricing Different credit cost per BP member type / PMPro level / MemberPress membership.
Group-scoped moderation BP group admins approve/reject jobs on their group's board.

Why it matters

If you run a community-and-careers site (developer guild, alumni network, professional association), you already have engaged members inside groups. WP Career Board Pro turns each group into its own job board with the same chrome BuddyPress members are used to - no separate "jobs admin" experience to learn.

What you do not need

  • No additional plugins. Standard BuddyPress + WP Career Board Pro is enough.
  • No theme changes. The Jobs group tab and member-directory chips are added via standard BP nav and query hooks - the active theme styles them automatically.
  • No data sync. The board is a real wcb_board post linked to the group via post-meta - every Free + Pro feature (credits, moderation, REST, alerts) works on it without extra wiring.

Where to next

Group-scoped Job Boards

Every BuddyPress group on your site automatically becomes its own job board. Members of the group post jobs that show up on a "Jobs" tab in the group navigation - and only on that tab. The main site-wide job board is unaffected.

How it works

When a BuddyPress group is created, BpGroupBoards listens on groups_created_group and creates a matching wcb_board CPT post. The two are linked through post-meta:

  • wcb_board post → _wcb_bp_group_id = BP group id
  • BP group → _wcb_board_id group-meta = wcb_board post id

The board's title stays in sync with the group's name automatically.

What members see

A new Jobs tab appears in the group navigation, between Members and Manage. Inside the tab is the standard Free job-listings block scoped to the group's board - same search, chip filters, infinite scroll, and bookmarking as the public job board.

Existing groups

Groups created before WP Career Board Pro 1.1.0 get a board lazily on the first time anybody visits the group's Jobs tab. There is no bulk backfill to run.

Posting a job to a group

Group members with the wcb_post_jobs ability see a Post a Job button at the top of the group's Jobs tab. Clicking it opens the single-page or multi-step form (whichever the site admin has configured on the global "Post a Job" page) pre-scoped to the group's board - so the new job lands on the group, not the site-wide board.

Group admins can moderate their own jobs

By default only admins with the global wcb_moderate_jobs ability can approve / reject jobs. Group admins and mods get an exemption for their own group's board - see Group-scoped moderation.

Privacy modes

BP group privacy What is visible on the Jobs tab
Public Anyone (logged-in or not) sees the jobs
Private Only group members see the jobs
Hidden Only group members see the tab - non-members cannot see the group, the tab, or the jobs

The board's REST endpoints respect the same gates - non-members hitting /wcb/v1/jobs?board_id=<group_board_id> on a private group get a 403.

Advanced - link an existing board

If you already have a manually-created wcb_board and want to link it to a group instead of letting the integration auto-create one:

add_action( 'init', function () {
    update_post_meta( $existing_board_id, '_wcb_bp_group_id', $group_id );
    groups_update_groupmeta( $group_id, '_wcb_board_id', $existing_board_id );
});

The integration uses the link in both directions - no further wiring needed.

Activity Stream Entries

Job and hiring milestones automatically post to the BuddyPress activity stream so the community can see what is happening across the careers side of the site.

What posts

Trigger Component Where it shows
Job approved (live on the board) wcb Site-wide activity feed
Job approved on a group's board groups The group's activity tab + site-wide feed
Application moves to Hired wcb Site-wide activity feed
Application moves to Hired on a group board groups Group activity + site-wide feed

What the entry looks like

  • Job approval: "Acme Inc posted a new job: Senior Backend Engineer." - links to the job single page.
  • Hire: "🎉 Sarah Chen was hired for Senior Backend Engineer at Acme Inc." - links to the candidate's profile + the job.

The exact wording is filterable - see Customising activity copy below.

What does not post

By design the integration does not post on:

  • Pending jobs - only approved (live) jobs appear in the activity feed; the moderation queue is private.
  • Application submitted / under review / shortlisted / not selected - these are private to the candidate (#notifications-wcbp)) so a public stream doesn't shame people through the funnel.

Disabling activity entries

If you want to keep the site quiet - for example a careers extension on a community site where members don't want job firehose in their feed - disable the actions:

remove_action( 'wcb_job_approved',                'WCB\Pro\Integrations\Buddypress\BpActivity::on_job_approved' );
remove_action( 'wcb_application_status_changed',  'WCB\Pro\Integrations\Buddypress\BpActivity::on_application_status_changed' );

Customising activity copy

Filter the activity content before it posts. Both filters receive the default content string + the relevant entity ids so you can pull post meta and re-template:

add_filter( 'wcb_bp_activity_job_approved_text', function ( $text, $job_id, $user_id ) {
    return sprintf(
        '🚀 New role at %s - %s',
        get_the_title( get_post_meta( $job_id, '_wcb_company_id', true ) ),
        get_the_title( $job_id )
    );
}, 10, 3 );
add_filter( 'wcb_bp_activity_hired_text', function ( $text, $application_id, $candidate_id ) {
    // shorten or rewrite the celebration message
    return $text;
}, 10, 3 );

Candidate Notifications

Every change to a candidate's application - submitted, under review, shortlisted, hired, not selected - pushes a notification into the candidate's BuddyPress notification bell.

This sits alongside the email notifications the candidate already receives. The bell badge nudges people back to your community when they're already on-site (where they're more likely to apply for another job, complete their profile, or post in a group).

What candidates see

Application status Bell notification
Submitted "Application received for Senior Backend Engineer at Acme Inc."
Under review "Acme Inc started reviewing your application for Senior Backend Engineer."
Shortlisted "You were shortlisted for Senior Backend Engineer at Acme Inc."
Hired "🎉 You were hired for Senior Backend Engineer at Acme Inc."
Not selected "Update on your Senior Backend Engineer application at Acme Inc."

Clicking the notification takes the candidate to My Applications in their candidate dashboard, scrolled to the affected application.

Where the strings live

Each verb is wrapped in __() with text domain wp-career-board-pro. Translate them via Loco Translate, WPML, or Polylang the same way you'd translate any other plugin string.

Custom statuses

If you've added custom application statuses via the wcb_application_statuses filter (Free), the notification verb falls back to a generic "Your application status changed to: " phrasing for unknown statuses.

To register a custom verb for your custom status:

add_filter( 'wcb_bp_notification_verbs', function ( $verbs ) {
    $verbs['phone_screen'] = __( 'You have a phone screen scheduled for %s at %s.', 'my-theme' );
    return $verbs;
});

Each verb is a sprintf() template - %1$s becomes the job title, %2$s becomes the company name.

Disabling the integration

remove_action( 'wcb_application_status_changed', 'WCB\Pro\Integrations\Buddypress\BpProIntegration::notify_candidate_status_change' );

Member Directory Filters

Two new chips appear above the member list at /members/:

  • Open to work - members with a public resume marked open-to-work.
  • Hiring - members with at least one currently published job.

Clicking a chip filters the BP member loop in place - same chrome, same paging, same theme styling. No new pages, no new templates.

How it works

BpMemberFilters hooks bp_after_has_members_parse_args and amends the underlying BP_User_Query with an 'include' => array of user ids that match the chip:

  • "Open to work" - pulled from candidates whose wcb_resume post is publicly visible AND has _wcb_open_to_work meta = 1.
  • "Hiring" - pulled from authors of published wcb_job posts (de-duplicated).

Both lookups are cached per-request - no N+1.

What does not happen

  • No new database tables. The chips read existing post meta and post-author relationships.
  • No new menu items. The chips render via bp_directory_members_search_form so the active theme styles them automatically.
  • No registration prompts. Logged-out visitors see the chips and can use them - the filters work on public profile data only.

Disabling a single chip

Each chip's render and query is hookable:

// Hide the "Open to work" chip
add_filter( 'wcb_bp_member_filter_open_to_work_visible', '__return_false' );

// Hide the "Hiring" chip
add_filter( 'wcb_bp_member_filter_hiring_visible', '__return_false' );

Adding a custom chip

Hook wcb_bp_member_filter_chips to register a new chip and provide a callback that returns the array of matching user ids:

add_filter( 'wcb_bp_member_filter_chips', function ( $chips ) {
    $chips['mentors'] = array(
        'label'    => __( 'Open to mentor', 'my-theme' ),
        'callback' => static fn() : array => get_users( array(
            'meta_key'   => 'open_to_mentor',
            'meta_value' => '1',
            'fields'     => 'ID',
        ) ),
    );
    return $chips;
});

Tiered Credit Pricing

Charge different credit costs to different members. A premium PMPro level might post jobs for half the credits. Free BP members might pay double. Anything in between, configurable as a matrix.

Loaded outside the BP gate. This integration runs on PMPro / MemberPress sites without BuddyPress too - it just reads which source(s) the user belongs to and looks up the cheapest tier.

How it works

BpTieredCreditCost hooks the wcbp_consumer_cost filter (registered on both the job_post and featured_upgrade consumers in the credits SDK). It reads a single option - wcbp_credit_cost_matrix - keyed by:

consumer × source × slug → credit cost

When a user posts a job (or upgrades a job to featured), the integration walks every source the user belongs to, reads the matrix, and applies the cheapest applicable tier.

The matrix shape

update_option( 'wcbp_credit_cost_matrix', array(
    'job_post' => array(
        'bp_member_type'           => array(
            'mentor' => 0,    // BP member type "mentor" posts free
            'company' => 5,
        ),
        'pmpro_level'              => array(
            'pro'     => 5,
            'premium' => 0,
        ),
        'memberpress_membership'   => array(
            'pro' => 5,
        ),
    ),
    'featured_upgrade' => array(
        'pmpro_level' => array(
            'premium' => 0,   // premium members upgrade for free
        ),
    ),
));

If a user is both pmpro_level=premium (cost 0) and bp_member_type=company (cost 5), the integration picks 0 because "cheapest tier wins."

Configuring via the admin UI

Career Board → Settings → Credits → Tiered Pricing. The matrix is exposed as a table - one row per (consumer × source × slug) - with a credit-cost number input on each row. Saving the table writes straight to wcbp_credit_cost_matrix.

Free posting for paid members

The most common configuration: free job posts for paying members.

PMPro level job_post cost
(none - free signup) 10
Pro 5
Premium 0

Set the base _wcb_board_settings.credit_cost on the board to 10 (paid floor for non-members), then add discounts in the matrix for paid levels. Premium members never see a credit prompt.

Tier resolution rules

  1. Walk every source the user is in (BP member type + every PMPro level + every MemberPress membership).
  2. For each source, look up wcbp_credit_cost_matrix[<consumer>][<source>][<slug>].
  3. Collect every match into an array of integers.
  4. Return the minimum. If no match, return the base cost (the board's credit_cost for job_post, or wcbp_featured_upgrade_cost for featured_upgrade).

Programmatic tweaks

// Always charge 10 for one specific company-owned employer regardless of their membership level
add_filter( 'wcbp_consumer_cost', function ( $cost, $user_id, $item_id, $board_id, $consumer ) {
    if ( 'job_post' === $consumer && in_array( 'enterprise_customer', wp_get_object_terms( $user_id, 'employer_tag', array( 'fields' => 'slugs' ) ), true ) ) {
        return 10;
    }
    return $cost;
}, 20, 5 );

The integration runs at priority 10 - your priority 20 overrides it.

Group-scoped Moderation

By default, only users with the global wcb_moderate_jobs ability can approve or reject pending jobs. On a community site that's usually just admins.

When a BP group has its own job board, that gate is too strict - group admins want to review jobs posted to their group without you having to grant them site-wide moderator powers.

This integration adds an exemption: BP group admins and moderators can approve / reject pending jobs on their group's board only.

How it works

Free 1.1.0 introduces a hookable ability check:

$can = apply_filters( 'wcb_moderate_jobs_ability_check', $can, $user_id, $job_id );

Pro hooks this filter via BpGroupBoards::allow_group_admins_to_moderate(). For each pending-job moderation request:

  1. Load the job's _wcb_board_id post-meta.
  2. Load that board's _wcb_bp_group_id post-meta - exit if 0.
  3. Check if $user_id is a member of that group with role admin or mod (groups_is_user_admin / groups_is_user_mod).
  4. If yes, return true. The user can moderate this specific job, even without the global ability.

The check is job-scoped, so a group admin in group A cannot moderate jobs posted to group B.

What's covered

Action Group admin can do it?
Approve / publish a pending job on their group
Reject a pending job on their group
Edit a published job on their group ✅ (existing post-author gates apply)
Approve a job on a different group
Approve a site-wide pending job (not on any group's board)
See the global moderation queue at Career Board → Moderation

Group admins moderate from the Jobs tab inside their group, not from the global moderation screen - the job listing on the group's Jobs tab shows pending jobs to group admins (only) with an inline approve / reject control.

Disabling the exemption

If you want to keep moderation strictly global (only users with wcb_moderate_jobs can approve, even group admins):

remove_filter( 'wcb_moderate_jobs_ability_check', 'WCB\Pro\Integrations\Buddypress\BpGroupBoards::allow_group_admins_to_moderate' );

Auditing approvals

Approvals fire wcb_job_approved regardless of which user approved. If you want to log who approved a group-board job:

add_action( 'wcb_job_approved', function ( $job_id ) {
    $approver_id = get_current_user_id();
    $board_id    = (int) get_post_meta( $job_id, '_wcb_board_id', true );
    $group_id    = (int) get_post_meta( $board_id, '_wcb_bp_group_id', true );
    if ( $group_id ) {
        // Log: $approver_id approved $job_id on group $group_id
    }
});

Multi-Board

Run unlimited independent job boards from one site.

Multi-Board Engine

The Multi-Board Engine lets you run multiple independent job boards from one WordPress install. Each board has its own set of jobs, employers, and settings - all managed from a single 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 a job (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 assign or reassign boards from WP Career Board → Jobs → Edit Job.

Board Switcher Block

Add the Board Switcher block to your jobs page to let visitors filter listings by board:

  1. Open your jobs page in the WordPress editor
  2. Insert the Board Switcher block above the Job Listings block
  3. Save

The switcher renders as a tab bar showing all active boards. Clicking a tab updates the Job Listings block to show only jobs from that board - no page reload.

Page layout with Board Switcher:

[ Board Switcher: All Jobs | Tech | Marketing | Remote ]
[ Job Search ] [ Job Filters ]
[ Job Listings ]

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 on any board.

Per-Board Settings

Each board has its own settings configured from the board's edit screen in wp-admin (WP Career Board → Boards → Edit Board):

Setting Default Description
Credit Cost Per Job 1 Credits required to post a job on this board. Set to 0 for free posting.
Moderation Auto-publish Whether jobs go live immediately or require admin approval
Job Expiry (days) 30 Days before a job listing automatically expires
Currency USD Currency for salary display on this board
Map Provider OpenStreetMap Map provider for the Job Map block on this board
Enable AI Features Off Enable the AI Chat Search for jobs on this board

Jobs on a premium board (credit cost > 0) are automatically marked as Featured, giving them priority sorting and the Featured badge in listings.

Per-Board Pipeline Stages

Each board can have its own set of application pipeline stages:

  1. Go to WP Career Board → Settings → Pipeline
  2. Use the Board dropdown to select a board
  3. Configure stages for that board independently

Employer Access

Employers are assigned to a board (or multiple boards) by the admin. Employers only see jobs and applications for their assigned boards.

To assign an employer to a board:

  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

Job Map

Interactive map view of job listings by location.

Job Map

The Job Map block displays an interactive map of job locations alongside your job listings. As candidates filter jobs, the map updates in real time to show only the matching pins.

How It Works

The Job Map block 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 jobs that match - no page reload.

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

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 placement is beside or below the Job Listings block

Recommended layout:

[ Job Search ] [ Job Filters ]
[ Job Map     ] [ Job Listings ]

This two-column layout (Job Map on the left, Job Listings on the right) gives candidates both the spatial and list view simultaneously.

Block Settings

In the block sidebar:

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 on the map rather than a specific pin location. This keeps the map accurate without forcing a geographic pin for fully remote roles.

Map Provider

WP Career Board Pro supports three map providers. You can set a global default or override it per board.

Provider API Key Required Notes
OpenStreetMap (Leaflet) No Default. Works out of the box. Geocoding via Nominatim.
Google Maps Yes Requires a Google Maps JavaScript API key
Mapbox Yes Requires a Mapbox public token

Setting the Global Map Provider

  1. Go to WP Career Board → Settings → Maps
  2. Choose your provider
  3. Paste your API key (Google or Mapbox only)
  4. Click Save Changes

Setting a Per-Board Provider

Each board can override the global provider. See Board Settings to configure a different provider for a specific board.

Geocoding

When a job is saved, WP Career Board Pro geocodes the job's location taxonomy term and stores the coordinates as post meta (_wcb_lat, _wcb_lng). This happens automatically - no manual coordinates needed.

Job Alerts

Keyword and location alerts for candidates.

Job Alerts

Job Alerts let candidates subscribe to saved searches. When new jobs matching their filters are posted, they receive an automatic email digest.

Three Ways Candidates Create Alerts

1. "Alert me" Button on Job Listings

When browsing jobs, a bell icon "Alert me" button appears in the toolbar next to the results count. Clicking it saves the current search query and active filters as a daily alert. The button turns green with "Alert saved" to confirm.

2. After Applying for a Job

After submitting an application, candidates see a "Get notified about similar jobs" prompt below the success message. This auto-creates an alert matching the applied job's category, type, and remote status - zero effort for the candidate.

3. From the Candidate Dashboard

Candidates can view and manage all their alerts from Candidate Dashboard → Job Alerts. The tab shows each alert with its search query, filter pills, and frequency selector.

Frequency Options

Frequency When emails send
Instant As soon as a matching job is published
Daily Once per day, morning digest
Weekly Once per week, Monday morning

Candidates can change frequency at any time from the dashboard.

What Gets Matched

Each alert stores criteria that are checked against every new job:

  • Keywords - matched against the job title
  • Category - job must be in the same category
  • Job Type - full-time, part-time, contract, etc.
  • Location - matches the location taxonomy
  • Salary Range - job salary falls within the candidate's range
  • Remote - remote-only filter

Setting Up (Admin)

Email Delivery

Job alert emails use WP Career Board's standard email system:

  1. Go to WP Career Board → Settings → Notifications
  2. Set your From Name and From Email

For reliable delivery, configure an SMTP plugin or use the Advanced Notifications settings (Settings → Emails → Provider) to route alerts through SendGrid, Mailgun, or Amazon SES.

Cron Schedule

Alerts rely on WP-Cron for daily and weekly digests:

  • Daily digest fires at 8:00 AM (server time)
  • Weekly digest fires Monday 8:00 AM

If your site has low traffic, consider a server-side cron job (wp cron event run --due-now) to ensure timely delivery.

Managing Alerts (Candidate)

From Candidate Dashboard → Job Alerts:

  • View all active alerts with filter pills (category, type, location, remote)
  • Change frequency using the dropdown selector
  • Delete an alert
  • Nav badge shows total alert count
  • Overview stat card links directly to the alerts tab

Unsubscribing

Every job alert email includes an Unsubscribe link at the bottom. Clicking it removes that specific alert immediately.

Job Feed

RSS, JSON, and XML feeds for every board.

Job Feed - Overview

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.

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.

Analytics

Credit, job, and applicant analytics with CSV export.

Analytics - Overview

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.

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

AI Features

AI-assisted job description writing.

AI Features

WP Career Board Pro 1.1.1 adds three AI-powered touchpoints: job embeddings + AI Chat Search, AI Description Writer on the post-a-job form, and AI match / rank REST data for custom integrations.

The full AI documentation lives in the Free plugin's docs section. That section covers Free's hook surface and Pro's feature set in one place so customers see the upgrade path right where they browse. This page is a short index - for setup, usage, blocks, hooks, and troubleshooting, follow the links below.

The full AI guide

Topic Where to read
What AI does + 1.1.1 shipping list + planned-for-future split docs/ai-features/overview
Picking a provider + setup walkthrough docs/ai-features/setup-and-providers
Candidate-side: AI Chat Search docs/ai-features/for-candidates
Employer-side: Description Writer + ranking REST docs/ai-features/for-employers
Block + REST + filters for add-on authors docs/ai-features/blocks-and-developers
Troubleshooting docs/ai-features/troubleshooting

At a glance (1.1.1)

Feature Surface in 1.1.1
Job embeddings on publish Auto - hooks wcb_job_created
AI Chat Search Block wcb/ai-chat-search + POST /wcb/v1/ai/match
AI Description Writer "Generate with AI" button on post-a-job form + POST /wcb/v1/jobs/ai-description
Candidate-to-job matches GET /wcb/v1/candidates/{id}/matches (no built-in UI)
Application ranking GET /wcb/v1/ai/ranked-applications/{job_id} (no built-in UI)

The three supported providers:

Provider When to pick it
OpenAI Default. Best balance of quality, cost, zero setup.
Anthropic Claude Better description copy. Needs OpenAI / Ollama alongside for embeddings.
Ollama Self-hosted. No data leaves your server. Requires server CPU / GPU.

Configure under WP Admin → Career Board → Settings → AI Settings once Pro is licensed.

What 1.1.1 does NOT ship

Listed honestly so expectations are calibrated:

  • No resume parser - the filter wcbp_candidate_resume_data exists for add-ons; Pro core doesn't ship a parser.
  • No AI fit-score column in the admin applications screen.
  • No background reindex - existing jobs don't auto-backfill.
  • No "Test connection" button - validate via a real generation.
  • No WP-CLI wp wcb ai * commands.
  • No AI lifecycle action hooks (no wcbp_ai_*_completed events).
  • No shortcode wrapper for the AI Chat Search block.

If any blocks your use case, file on the support board.

Why the docs live in Free

Most WP Career Board users start on Free and decide whether to upgrade after seeing what Pro adds. Documenting Pro AI features inside Free's docs means the upgrade story is visible right where users browse - no second site to discover, no separate index to maintain. This is deliberate, not a doc-organisation accident.

For all hands-on detail (setup, flows, hooks, troubleshooting), open the Free links above.

Related Pro developer docs

Notifications

Email and BuddyPress notification templates.

Notifications - Overview

WP Career Board Pro adds two notification layers on top of the Free plugin's email system: an in-app notification bell that employers and candidates see inside their dashboards, and Pro email types for job alerts, credit top-ups, and low credit balance warnings.

In-App Notification Bell

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.

Pro Email Notifications

The notifications-pro module extends the Free plugin's email system with three additional transactional emails. You can customise the subject line and enable or disable each email from Career Board → Settings → Emails.

Job Alert Digest

  • Recipient: Candidate
  • Trigger: wcbp_send_alert_email action - 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 Stripe Checkout
  • Content: Confirmation of the purchase and updated balance

Low Credit Balance Warning

  • Recipient: Employer
  • Trigger: wcbp_credits_low action - 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.

Configuring Email Settings

  1. Go to Career Board → Settings → Emails
  2. Toggle any email on or off
  3. Edit the subject line for each email type
  4. Click Save

Changes take effect immediately for the next triggered email.

Migration

Import from WP Job Manager and CSV.

Migration & CSV Import - Overview

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.

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 programmatically. Use WP-CLI or a one-time admin action:

$importer = new \WCB\Pro\Modules\Migration\WpjmImporter();
$result   = $importer->import();
// $result: [ 'imported' => N, 'skipped' => N, 'errors' => [...] ]

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.

PWA

Progressive Web App with installable manifest and service worker.

PWA - Overview

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.

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.

Pro Blocks Reference

Every Pro block, its attributes, and example uses.

Pro Blocks Reference

WP Career Board Pro adds 15 blocks to the WordPress block inserter. All Pro blocks are in the wcb/ namespace and appear in the block inserter only when WP Career Board Pro is active.

Blocks at a Glance

Block Name in Inserter What It Does
wcb/ai-chat-search AI Chat Search Natural language job search powered by AI
wcb/application-kanban Application Kanban Drag-and-drop Kanban board for pipeline stages
wcb/board-switcher Board Switcher Tab bar for switching between job boards
wcb/credit-balance Credit Balance Employer credit balance with transaction history
wcb/featured-candidates Featured Candidates Sidebar widget listing featured public resumes
wcb/featured-companies Featured Companies Sidebar widget listing featured companies
wcb/job-alerts Job Alerts Subscription form for saved job search alerts
wcb/job-map Job Map Interactive map of job locations
wcb/my-applications My Applications Candidate's submitted applications list
wcb/open-to-work Open to Work Sidebar widget listing candidates open to work
wcb/resume-archive Find Resumes Public archive of candidate resumes
wcb/resume-builder Resume Builder Section-by-section resume editor for candidates
wcb/resume-map Resume Map Map showing candidate locations
wcb/resume-search-hero Resume Search Hero Full-width resume search form
wcb/resume-single Resume Single Public-facing view of a single candidate resume

Where to Add Each Block

Block Recommended Page
AI Chat Search Jobs page - in place of or above the standard Job Search block
Application Kanban Employer Dashboard page (auto-added when Pipeline is enabled)
Board Switcher Jobs page - above the Job Listings block
Credit Balance Employer Dashboard or any employer-facing page
Featured Candidates Homepage sidebar, company pages
Featured Companies Homepage sidebar, jobs page sidebar
Job Alerts Jobs page - below or beside the Job Listings block
Job Map Jobs page - alongside Job Listings and Job Filters
My Applications Candidate Dashboard page
Open to Work Homepage sidebar, employer-facing pages
Find Resumes Any public page - e.g., "Find Candidates"
Resume Builder Candidate Dashboard page or a dedicated Resume page
Resume Map Find Candidates page - alongside Find Resumes
Resume Search Hero Find Candidates page - above Find Resumes
Resume Single The wcb_resume post template (auto-assigned by setup)

Block Details


wcb/ai-chat-search - AI Chat Search

Natural language job search powered by semantic AI. Candidates type a conversational query - "remote product manager role with equity" - and get semantically matched results using vector similarity.

Attributes:

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

Usage notes: Requires the AI module to be configured with a provider key. Go to WP Career Board → Settings → AI Settings to connect your AI provider (OpenAI, Claude, or Ollama). Uses the WordPress Interactivity API.


wcb/application-kanban - Application Kanban

A drag-and-drop Kanban board showing applicant cards organized by pipeline stage. Employers drag cards between columns to advance or reject candidates.

Attributes:

Attribute Type Default Description
jobId integer 0 Scope the board to a specific job. 0 shows all jobs.

Usage notes: Automatically added to the Employer Dashboard when the Application Pipeline module is enabled. See Application Pipeline. Uses the WordPress Interactivity API.


wcb/board-switcher - Board Switcher

A tab bar that lets visitors switch between different job boards. Updates the shared wcb-search Interactivity API store to filter Job Listings to the selected board - no page reload.

Attributes: None

Usage notes: Place above the Job Listings block on your jobs page. Only renders visible tabs when two or more boards exist. See Multi-Board Engine.


wcb/credit-balance - Credit Balance

Displays the logged-in employer's current credit balance, a Buy Credits button, and a recent transaction history panel.

Attributes:

Attribute Type Default Description
showHistory boolean true Show or hide the recent transaction list
historyCount integer 5 Number of recent transactions to display

Usage notes: Reads the logged-in employer's balance automatically. Shows nothing to non-employer users. Uses the WordPress Interactivity API.


wcb/featured-candidates - Featured Candidates

A static sidebar widget listing featured public candidate resumes. Useful for drawing employer attention to available talent.

Featured Candidates block

Attributes:

Attribute Type Default Description
count integer 5 Number of candidates to display (1-20)
title string "" Optional heading above the list
showViewAll boolean true Show a "View All" link below the list
viewAllUrl string "" URL for the "View All" link

Usage notes: Displays candidates who have at least one public resume. Set viewAllUrl to your Find Candidates page URL. Skill pills render directly from the wcb_resume_skill taxonomy and fall back to _wcb_resume_skills meta values when the taxonomy is empty (1.2.0+) - candidates whose skills-sync hook never ran still display correctly.


wcb/featured-companies - Featured Companies

A static sidebar widget listing featured companies with their open role counts.

Attributes:

Attribute Type Default Description
count integer 5 Number of companies to display (1-20)
title string "" Optional heading above the list
showViewAll boolean true Show a "View All" link below the list
viewAllUrl string "" URL for the "View All" link

Usage notes: Shows companies with at least one active job. Each company card shows the company logo, name, and open job count.


wcb/job-alerts - Job Alerts

A subscription form that reads the current search state and lets logged-in candidates save their active filters as a job alert.

Attributes: None

Usage notes: Shares the same wcb-search Interactivity API store as Job Listings and Job Filters. When a candidate clicks Save Alert, the current keyword, category, type, location, salary range, and remote filter are saved. Frequency (instant/daily/weekly) is set from the Candidate Dashboard. See Job Alerts.


wcb/job-map - Job Map

An interactive Leaflet map showing job pin locations, synced with the Job Listings block search state. When a visitor filters jobs, the map updates in real time.

Attributes:

Attribute Type Default Description
height integer 480 Map canvas height in pixels

Usage notes: Jobs must have a Location taxonomy term set. Coordinates are geocoded automatically on job save. Remote jobs appear in a special cluster rather than a geographic pin. See Job Map.


wcb/my-applications - My Applications

Renders the current user's submitted job applications as a semantic table with Job / Status / Submitted column headers (1.2.0+). On narrow viewports it collapses to a card layout via data-label attributes so mobile reads the same structure without horizontal scroll.

Candidate view (default) - shows the current user's own applications:

My Applications block - candidate view

Employer view - set the employerId attribute to surface a Job + Applicant view of every application across that employer's posted jobs:

My Applications block - employer view with Applicant column

Attributes:

Attribute Type Default Description
authorId integer 0 Show another user's applications (admin use only). 0 = current user.
employerId integer 0 Switch to employer view. 0 = candidate view. Permission-gated: only the employer themselves or a wcb_manage_settings admin can view another employer's pipeline.
perPage integer 20 Applications per page

Usage notes: The Status column always renders a badge (defaults to "Submitted" if the application's _wcb_status meta is empty), so the column is never blank. Status badges use the same .wcb-status-badge colour tokens as the candidate dashboard. Place on the Candidate Dashboard page (candidate view) or any employer-scoped page (employer view).


wcb/open-to-work - Open to Work

A static sidebar widget listing candidates who have set their profile status to "Open to Work."

Open to Work block

Each candidate card shows (1.2.0+):

  • Avatar - pulled from the resume form's uploaded photo (_wcb_resume_photo_id), with an initial-letter chip in the brand colour as the fallback. Never falls back to the BuddyPress / Gravatar avatar - the resume form is the canonical source for a candidate's professional photo on this block.
  • Name - display name
  • Headline - the current/most-recent experience entry's job title
  • Location - resume-level _wcb_resume_location meta, or the current experience entry's location when the resume-level field is blank
  • Years of experience - computed from the earliest start_date across all experience entries (e.g. "8+ years")
  • Skill pills - top 3 from the wcb_resume_skill taxonomy, with the same _wcb_resume_skills meta fallback as the Featured Candidates block

Attributes:

Attribute Type Default Description
count integer 5 Number of candidates to display (1-20)
title string "" Optional heading above the list
showViewAll boolean true Show a "View All" link below the list
viewAllUrl string "" URL for the "View All" link

Usage notes: Useful on employer-facing pages to surface actively available candidates. Candidate order is randomised on every load so the widget rotates exposure across everyone who is open to work, rather than always showing the same most-recently-saved set.


wcb/resume-archive - Find Resumes

A paginated, filterable archive of publicly visible candidate resumes. Displays avatar, name, job title, skills, and location for each resume card.

Attributes:

Attribute Type Default Description
perPage integer 12 Resumes per page
authorId integer 0 Scope to a specific user. 0 = all public resumes.
includePrivate boolean false Include private resumes (admin only)

Usage notes: Pair with wcb/resume-search-hero on the same page for the full "Find Candidates" experience. The Pro Setup Wizard creates this page automatically.


wcb/resume-builder - Resume Builder

A section-by-section resume editor for candidates covering work experience, education (school and college), skills, languages, certifications, and portfolio links. Supports multiple resumes per candidate.

Attributes: None

Usage notes: Requires the candidate to be logged in. Can run in standalone mode (dedicated page with ?resume_id= parameter) or embedded mode (same page as the Candidate Dashboard). See Resume Builder - Setup.


wcb/resume-map - Resume Map

An interactive Leaflet map showing candidate locations. Clicking a pin navigates to that candidate's public resume profile.

Attributes:

Attribute Type Default Description
height integer 480 Map canvas height in pixels

Usage notes: Pair with wcb/resume-archive on the Find Candidates page to give employers a spatial view of talent. Candidate coordinates come from their profile location. Uses the WordPress Interactivity API.


wcb/resume-search-hero - Resume Search Hero

A full-width search form for the candidate archive. Supports keyword search plus optional skill filter and open-to-work filter.

Attributes:

Attribute Type Default Description
layout string "horizontal" Form layout - horizontal or vertical
placeholder string "" Search input placeholder text
buttonLabel string "" Search button label
showSkillFilter boolean true Show the skill filter dropdown
showOpenToWorkFilter boolean false Show the open-to-work toggle filter

Usage notes: Place above wcb/resume-archive on your Find Candidates page. The Pro Setup Wizard adds both blocks to the Find Candidates page automatically.


wcb/resume-single - Resume Single

The public-facing resume view for a single candidate. Renders all resume sections in a formatted layout.

Attributes: None

Supports: wide and full alignment.

Usage notes: Place on the wcb_resume post type template. The Pro setup assigns this block to the resume template automatically - you typically do not need to add it manually. Does not accept custom HTML.


Adding a Pro Block

  1. Open any page in the WordPress editor
  2. Click + to add a block
  3. Search for the block name (e.g., "Job Map")
  4. Click to insert

All Pro blocks appear in the Widgets category in the block inserter.

Developer Guide

Hooks reference, REST API, and extending Free.

Developer Guide - Overview

WP Career Board Pro is built as an extension of WP Career Board (Free), not a fork. Every Pro feature consumes Free's hooks; Free never knows specifically about Pro. The runtime guard (wcbp_free_active()) makes sure Pro degrades gracefully when Free is deactivated.

Use this guide when:

  • You're writing an addon that consumes Pro features (resume builder, application kanban, credit SDK).
  • You're auditing the Free/Pro coupling contract.
  • You're writing a custom credit-gateway adapter.

For Free-side dev surface (the 92 hooks, REST endpoints, CLI commands every site is built on), start with the Free developer guide.

Free/Pro coupling contract

Pro extends Free via four enforced invariants (plan/INVARIANTS.yaml A-group). The local-CI gate fails any commit that violates these:

ID Title What it guards
A1 Lockstep version WCBP_VERSION always equals WCB_VERSION. Half-installs (one updated, the other not) are impossible.
A2 Dependency guard Pro defines wcbp_free_active() and uses it to gate boot. Deactivating Free does not fatal Pro.
A3 REST namespace shared, paths disjoint Both register under wcb/v1; Free and Pro routes never collide.
A4 No source modification Pro hooks Free via documented filters only. Never patches Free's classes.

If you're shipping your own Pro-side addon, follow the same invariants - they're the operational contract that lets Pro and the addon coexist without one breaking the other.

Architecture at a glance

Layer Where Purpose
Blocks blocks/<name>/render.php + view.js 16 Pro blocks (kanban, alerts, resume, credit balance, AI chat, etc.)
REST API api/endpoints/class-*-endpoint.php 30+ Pro endpoints under wcb/v1/* extending Free's WCB\Api\REST_Controller
Modules modules/<area>/ Pro features: alerts, ai, analytics, boards, credits, fields, maps, migration, notifications, pipeline, pwa, resume
SDK vendor/wbcom-credits-sdk/ Wbcom Credits SDK (vendored). Adapter pattern: WooCommerce, WC Subscriptions, PMPro, MemberPress, Stripe direct, PayPal direct
Core core/class-*.php Lifecycle: ProInstall, ProPlugin, License, FreeCoordination

Contents

Doc What's inside
02-extending-free.md The canonical Pro-extends-Free contract - dependency guard, REST sharing, lockstep
03-hooks-reference.md Pro's own actions and filters
04-credits-sdk.md The Wbcom Credits SDK - adapters, gateways, ledger, idempotency

Working against Pro from a third-party plugin

To build an addon that depends on Pro:

  1. Declare Pro as a Requires Plugins: header in your main file.
  2. Gate your runtime hooks behind a defined( 'WCBP_VERSION' ) check.
  3. Verify your minimum Pro version with version_compare() against WCBP_VERSION.
  4. Hook into Pro's documented actions/filters from 03-hooks-reference.md. Never reach into internal classes - those aren't part of the public contract.

The full template (including composer arch-checks for your own addon) is in the Free repo's bin/architecture-checks.sh - copy it, change the namespace, add your invariants.

Extending Free - The Canonical Pro Contract

Pro is a worked example of "how to extend WP Career Board Free without forking." Every pattern here is something a third-party addon can copy verbatim.

The four invariants

The architecture-checks gate enforces these on every Pro commit. Your addon should aim for the same:

A1 - Lockstep version

Pro's WCBP_VERSION constant matches Free's WCB_VERSION at every commit. The pre-commit hook checks both files and fails the build on drift. Why: shipping one updated and the other not means a customer has a half-built release; cross-plugin hook signatures go out of sync.

For an addon, your equivalent is "what's the minimum Free version I work against?" Declare it as a constant (MYADDON_MIN_WCB = '1.1.1'), check at boot:

if ( ! defined( 'WCB_VERSION' )
     || version_compare( WCB_VERSION, MYADDON_MIN_WCB, '<' ) ) {
    add_action( 'admin_notices', 'myaddon_min_wcb_notice' );
    return;
}

A2 - Dependency guard

Pro defines wcbp_free_active() and uses it inside the boot path:

function wcbp_free_active(): bool {
    return defined( 'WCB_VERSION' );
}

if ( ! wcbp_free_active() ) {
    add_action( 'admin_notices', 'wcbp_missing_free_notice' );
    return;
}

The guard runs on plugins_loaded@20 - Free uses default priority 10, so by the time Pro's check fires Free has already booted. If a customer deactivates Free via WP-CLI (which bypasses the Requires Plugins: header), Pro detects it and gracefully skips its hooks instead of fataling.

A3 - REST namespace shared, paths disjoint

Both plugins register under the same wcb/v1 namespace - that's intentional so the API surface stays cohesive to consumers. Disjointness is what matters:

Free:  /jobs, /jobs/{id}, /applications/{id}, /candidates/{id} ...
Pro:   /resumes, /boards/{id}, /pipeline, /alerts ...

The architecture-checks gate (Pro's check_A3) reads both manifests' .rest.endpoints[].route and fails if any path appears in both. If you're adding routes from an addon, pick a unique sub-path and document it.

A4 - No source modification

Pro never patches Free's classes, never calls function_alias, never monkey-patches. All extension goes through documented filters and actions. The contract is one-way: Free exposes the hooks; Pro and other addons consume them.

How Pro consumes Free's hooks

The cleanest examples in the codebase:

Returning Pro's status to Free's gate filters

Free fires apply_filters( 'wcb_pro_active', false ) to check whether Pro is running. Pro registers:

// In core/class-free-coordination.php
add_filter( 'wcb_pro_active', '__return_true' );

Same pattern for wcb_pro_licensed, wcb_pro_version, wcb_pro_ai_enabled, wcb_pro_alerts_enabled, wcb_pro_resumes_enabled. Each returns a value Pro alone can authoritatively answer.

Bridging Free's credit filters to the SDK

Free fires wcb_employer_credit_balance as a 0-default filter. Pro intercepts and returns the real balance from the credit SDK:

add_filter( 'wcb_employer_credit_balance', function ( $balance, $user_id ) {
    return \Wbcom\Credits\Credits::get_balance( 'wp-career-board', $user_id );
}, 10, 2 );

Same approach for wcb_credit_purchase_url, wcb_board_credit_cost, wcb_credit_low_threshold. Free has the placeholder; Pro fills it.

Hooking the board picker to filter by group membership

Free's job-form template fires apply_filters( 'wcb_board_options_for_employer', $options, $user_id ). Pro's BP-groups integration consumes it to drop boards whose linked BuddyPress group the employer is not a member of:

add_filter( 'wcb_board_options_for_employer',
    array( BpGroupBoards::class, 'restrict_boards_to_user_groups' ),
    10, 2
);

This is the canonical pattern for "Pro adds a constraint to a Free control surface."

How Pro extends Free's blocks

Free's blocks render server-side. Pro extends them via two mechanisms:

1 - Server-side action injection

Free's job-form fires wcb_job_form_step1_fields, wcb_job_form_step2_fields, etc. at predictable points. Pro injects extra inputs:

add_action( 'wcb_job_form_step3_fields', function () {
    // Render Pro-only AI description toggle.
});

2 - REST response filtering

Every REST response goes through a wcb_rest_prepare_* filter. Pro adds Pro-specific fields:

add_filter( 'wcb_rest_prepare_application', function ( $row, $app, $request, $context ) {
    $row['kanban_stage'] = wcbp_get_application_stage( $app->ID );
    return $row;
}, 10, 4 );

These two patterns cover ~90% of Pro's UI extensions. Anything they can't handle is a real gap in Free's hook surface - file a Free PR to add the hook, then consume it from Pro.

How Pro adds new database tables

Pro owns 8 tables (wcb_credit_ledger, wcb_field_groups, wcb_field_definitions, wcb_field_values, wcb_job_boards, wcb_job_alerts, wcb_application_stages, wcb_ai_vectors). All creation goes through dbDelta() in core/class-pro-install.php:

private static function create_field_groups_table( $wpdb ): void {
    $table_name = $wpdb->prefix . 'wcb_field_groups';
    $charset    = $wpdb->get_charset_collate();
    $sql = "CREATE TABLE {$table_name} ( ... ) {$charset};";
    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta( $sql );
}

The pattern (one private method per table) makes the schema greppable. Schema version is tracked in wcbp_db_version option.

How Pro extends the credit-purchase flow

The Wbcom Credits SDK supports adapter classes. Pro registers each e-commerce plugin's adapter:

\Wbcom\Credits\Adapters\WooCommerce::register( 'wp-career-board' );
\Wbcom\Credits\Adapters\PMPro::register( 'wp-career-board' );
\Wbcom\Credits\Adapters\MemberPress::register( 'wp-career-board' );
\Wbcom\Credits\Adapters\WooSubscriptions::register( 'wp-career-board' );

Each adapter listens for that plugin's "order completed" event and writes a topup row to the ledger. To add support for a new e-commerce plugin, write a new adapter class (one method: register that hooks the relevant action). See 04-credits-sdk.md.

Pre-commit + pre-push checks

bin/architecture-checks.sh runs every gate (U1..U6, A1, A2, A3) on every push. If you're authoring against Pro:

composer arch-checks   # Run the gate manually anytime
composer ci            # Run the full pipeline (PHPStan, PHPCS, arch, journeys)

The pre-push git hook (one-time composer install-hooks activates it) runs composer ci:no-journeys before every push. Bypass for emergencies only: SKIP_LOCAL_CI=1 git push.

When the contract doesn't fit

If you find yourself wanting to do something the four invariants don't allow (e.g. modify Free source, register a colliding REST path), STOP and either:

  1. Open a PR against Free to add the missing extension point, or
  2. Build the feature inside Pro using a different mechanism, or
  3. Talk to the team - there's usually a third option we'd rather ship than break the contract.

The contract exists because we've shipped a paired plugin set for years; the four invariants are the things that broke when we tried to "just patch it this once." They're not bureaucracy - they're scar tissue.

Pro Hooks Reference

WP Career Board Pro fires 10 actions and 20 filters of its own (in addition to the ~92 Free hooks documented in the Free developer guide). Pro hooks use the wcbp_* prefix; Pro also participates in some wcb_* (Free namespace) hooks where it shares the contract surface with Free.

Actions Pro fires

Hook Args Use to
wcbp_application_stage_changed $app_id, $new_stage, $old_stage React when an application moves through the Kanban pipeline.
wcbp_board_deleted $board_id Cleanup when a Pro board is removed. Cascades to applications and stage data.
wcbp_credit_consumed $user_id, $amount, $context A deduct row was written to the credit ledger. Use for audit logging or per-purchase notifications.
wcbp_credit_hold_reconciled $user_id, $hold_id, $outcome When a held-credit row is finalised (deduct or refund).
wcbp_field_value_saved $field_id, $value, $entity_id A custom field on a job/application/resume was saved via the field builder.
wcbp_resume_published $resume_id, $candidate_id A candidate's resume went public. Use for search indexing or notifications.
wcbp_send_alert_email $alert_id, $matches Pro is about to send a job-alert email. Hook to send a parallel SMS, Slack, etc.

Pro also fires Free hooks in places where the action semantically belongs to Pro but the contract is shared:

Hook Where Pro fires it Why
wcb_application_status_changed modules/pipeline/class-pipeline-module.php Pipeline drag-and-drop moves an application; the status-changed event must fire even though the trigger is Pro-side.
wcb_resume_form_simple_extra_fields blocks/resume-form-simple/render.php Extension point for adding fields to the quick resume form.
wcb_job_csv_imported modules/migration/class-csv-importer.php After a bulk CSV import completes.

Filters Pro fires

AI

Hook Returns
wcbp_ai_provider_drivers array - registered AI provider drivers (Anthropic, OpenAI, custom)
wcbp_ai_provider_requires_api_key bool - does the active provider need a key?
wcbp_candidate_resume_data array - the resume data shape sent to AI for parsing/matching

Alerts

Hook Returns
wcbp_alert_dispatch_channels array - which channels to send job alerts through (email, in-bell-notification, future SMS/Slack)

Credits SDK

Hook Returns
wcbp_consumer_cost int - actual credits charged for a specific consumer (job_post, featured_upgrade). Tier-pricing happens here.

Kanban / pipeline

Hook Returns
wcbp_kanban_card_columns array - extra columns shown on each Kanban card

PWA

Hook Returns
wcbp_pwa_manifest array - the PWA manifest before it's served at /wp-json/wcb/v1/pwa-manifest

Resume builder

Hook Returns
wcbp_resume_groups array - the resume-form field groups (Personal, Experience, Education, Skills, etc.)
wcbp_resume_textarea_fields array - fields rendered as textareas vs single-line inputs
wcbp_resume_checkbox_fields array - fields rendered as checkboxes
wcbp_resume_date_fields array - fields formatted as date inputs
wcbp_resume_field_label string - override the label of a specific field
wcbp_resume_pdf_renderer callable - swap out the resume-to-PDF rendering engine

Pro also extends these Free filters:

Hook What Pro returns
wcb_board_credit_cost The per-board credit cost based on the Pro Boards admin config.
wcb_job_republish_credit_cost The cost to republish, with Pro tier discounts applied.
wcb_rest_prepare_board Adds Pro-specific board metadata to the boards response.
wcb_rest_prepare_board_stage Pipeline-stage data shape.
wcb_rest_prepare_notification Notifications bell response shape.
wcb_rest_prepare_resume Resume profile shape.
wcb_resume_form_fields Resume form field schema.

Listening patterns

Send a Slack message when a job moves to "Hired"

add_action( 'wcb_application_status_changed', function ( $app_id, $new_status, $old_status ) {
    if ( 'hired' !== $new_status ) {
        return;
    }
    $job_id    = (int) get_post_meta( $app_id, '_wcb_job_id', true );
    $job_title = get_the_title( $job_id );
    wp_remote_post( SLACK_WEBHOOK, array(
        'body' => wp_json_encode( array( 'text' => "✅ Hire confirmed: {$job_title}" ) ),
        'headers' => array( 'Content-Type' => 'application/json' ),
    ));
}, 10, 3 );

Add a custom group to the resume builder

add_filter( 'wcbp_resume_groups', function ( $groups ) {
    $groups['portfolio'] = array(
        'label'  => __( 'Portfolio links', 'my-addon' ),
        'fields' => array(
            'github'    => array( 'type' => 'url', 'label' => 'GitHub' ),
            'linkedin'  => array( 'type' => 'url', 'label' => 'LinkedIn' ),
            'dribbble'  => array( 'type' => 'url', 'label' => 'Dribbble' ),
        ),
    );
    return $groups;
});

Tier the credit cost by user role

add_filter( 'wcb_board_credit_cost', function ( $cost, $board_id ) {
    if ( current_user_can( 'wcb_employer_pro_tier' ) ) {
        return max( 1, (int) ( $cost / 2 ) );  // 50% off for Pro-tier employers
    }
    return $cost;
}, 20, 2 );

How to confirm an arg signature

grep -rn "do_action\\s*(\\s*'wcbp_credit_consumed'" wp-content/plugins/wp-career-board-pro/

The result is the file:line where Pro fires the hook; read the surrounding lines for the parameter shapes.

Related

Wbcom Credits SDK

The credit system is built on the Wbcom Credits SDK - a vendored library at vendor/wbcom-credits-sdk/ that provides:

  • An append-only ledger (wp_wcb_credit_ledger table).
  • An adapter pattern for e-commerce plugins (WooCommerce, PMPro, etc.).
  • A gateway pattern for direct payment processors (Stripe, PayPal).
  • An idempotency layer (duplicate webhook deliveries don't double-credit).
  • A consumer pattern (entities that spend credits - job posting, featured upgrade).

This doc covers the contract for writing your own adapter or consumer.

Architecture

                    ┌────────────────────────────────────┐
                    │  Wbcom Credits SDK (vendored)     │
                    │                                    │
                    │  ┌──────────────┐                  │
                    │  │ Ledger       │  ← single source │
                    │  │ (DB writes)  │     of truth     │
                    │  └──────────────┘                  │
                    │        ↑                           │
                    │   ┌────┴────┐                      │
                    │   │         │                      │
                    │ Adapters  Gateways                 │
                    │ (Woo,     (Stripe,                 │
                    │  PMPro,    PayPal -                │
                    │  MEMP)     direct)                 │
                    └─────↑──────────↑───────────────────┘
                          │          │
                       on order   on webhook
                       completed   verified

Consumers - what can spend credits

A "consumer" is something the SDK debits credits FOR. Pro registers two consumers:

\Wbcom\Credits\Credits::register_consumer( 'wp-career-board', array(
    'id'        => 'job_post',
    'label'     => __( 'Posting a job', 'wp-career-board-pro' ),
    'cost'      => function ( $user_id, $context ) {
        return apply_filters( 'wcbp_consumer_cost', 1, $user_id, $context['item_id'] ?? 0, 'job_post' );
    },
    'hold_on'   => 'wcb_job_submitted',     // Hold credits when this action fires
    'deduct_on' => 'wcb_job_approved',      // Deduct (consume) when this fires
    'refund_on' => 'wcb_job_rejected',      // Refund when this fires
));

\Wbcom\Credits\Credits::register_consumer( 'wp-career-board', array(
    'id'        => 'featured_upgrade',
    'label'     => __( 'Featured upgrade', 'wp-career-board-pro' ),
    'cost'      => function ( $user_id, $context ) {
        return apply_filters( 'wcbp_consumer_cost', 5, $user_id, $context['item_id'] ?? 0, 'featured_upgrade' );
    },
    'hold_on'   => 'wcb_featured_upgrade_requested',
    'deduct_on' => 'wcb_featured_upgrade_completed',
    'refund_on' => 'wcb_featured_upgrade_failed',
));

To add a new consumer (e.g. "boosted job alert"):

add_action( 'init', function () {
    \Wbcom\Credits\Credits::register_consumer( 'wp-career-board', array(
        'id'        => 'boosted_alert',
        'label'     => __( 'Boosted job alert', 'my-addon' ),
        'cost'      => fn( $u, $c ) => 3,
        'hold_on'   => 'myaddon_boost_requested',
        'deduct_on' => 'myaddon_boost_dispatched',
        'refund_on' => 'myaddon_boost_failed',
    ));
});

Fire your custom action when the relevant lifecycle events happen in your code - the SDK takes care of the ledger writes.

Adapters - automatic credit grants from e-commerce plugins

An "adapter" listens for a specific plugin's "order completed" event and writes a topup ledger row. Pro ships four adapters:

Adapter File Listens to
WooCommerce vendor/wbcom-credits-sdk/src/Adapters/WooCommerce.php woocommerce_order_status_completed
WC Subscriptions vendor/wbcom-credits-sdk/src/Adapters/WooSubscriptions.php wcs_subscription_payment_complete
Paid Memberships Pro vendor/wbcom-credits-sdk/src/Adapters/PMPro.php pmpro_after_change_membership_level + pmpro_subscription_payment_received
MemberPress vendor/wbcom-credits-sdk/src/Adapters/MemberPress.php mepr-event-transaction-completed

Each adapter implements AdapterInterface:

interface AdapterInterface {
    public static function register( string $slug ): void;
    public static function is_available(): bool;
    public static function get_label(): string;
    public static function get_products(): array;  // For the admin mapping UI
}

To add a new adapter (e.g. for Easy Digital Downloads):

namespace MyAddon\Credits;

use Wbcom\Credits\Adapters\AdapterInterface;
use Wbcom\Credits\Credits;

class EDD implements AdapterInterface {

    public static function register( string $slug ): void {
        if ( ! self::is_available() ) {
            return;
        }
        add_action( 'edd_complete_purchase', function ( $payment_id ) use ( $slug ) {
            $user_id = (int) edd_get_payment_user_id( $payment_id );
            $items   = edd_get_payment_meta_cart_details( $payment_id );
            foreach ( $items as $item ) {
                $credit_amount = (int) self::get_credit_amount_for_product( $slug, (int) $item['id'] );
                if ( $credit_amount > 0 ) {
                    Credits::topup( $slug, $user_id, $credit_amount, array(
                        'source'     => 'edd',
                        'order_id'   => $payment_id,
                        'product_id' => (int) $item['id'],
                    ));
                }
            }
        });
    }

    public static function is_available(): bool {
        return class_exists( 'Easy_Digital_Downloads' );
    }

    public static function get_label(): string {
        return 'Easy Digital Downloads';
    }

    public static function get_products(): array {
        // Return EDD products in the shape the admin UI expects.
    }

    private static function get_credit_amount_for_product( string $slug, int $product_id ): int {
        $mappings = (array) get_option( "{$slug}_credit_mappings", array() );
        foreach ( $mappings as $row ) {
            if ( 'edd' === ( $row['adapter'] ?? '' ) && (int) $row['item_id'] === $product_id ) {
                return (int) $row['credits'];
            }
        }
        return 0;
    }
}

// Register on plugins_loaded so it runs after EDD is available.
add_action( 'plugins_loaded', function () {
    MyAddon\Credits\EDD::register( 'wp-career-board' );
}, 20 );

Gateways - direct payment processors

A "gateway" is for selling credits directly without an e-commerce plugin in between (Stripe Checkout, PayPal Smart Buttons). The SDK ships two gateways: Stripe and PayPal.

The customer-facing checkout flow (block + REST endpoint that creates a checkout session) is queued for 1.1.2 - until it ships, the gateways exist but aren't reachable from the storefront. The webhook side works today, so refunds initiated in the provider dashboard still flow back to the ledger.

If you're writing a custom gateway, implement GatewayInterface (in vendor/wbcom-credits-sdk/src/Gateways/GatewayInterface.php):

interface GatewayInterface {
    public function get_id(): string;
    public function get_label(): string;
    public function get_settings_fields(): array;
    public function create_checkout( string $slug, int $user_id, int $credits,
                                     int $price_cents, string $currency = 'USD',
                                     ?string $return_url = null ): string;
    public function handle_webhook( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error;
}

Once registered via Gateway_Registry::register(), the admin UI auto-discovers it.

The ledger

Every credit movement writes one row. Schema (since v1.3.0):

Column Type Notes
id bigint(20) PK Auto-increment
slug varchar(60) Plugin slug (wp-career-board) - supports multi-tenant SDK use
user_id bigint(20) Renamed from employer_id in 1.1.1
item_id bigint(20) Renamed from post_id in 1.1.1 - the consumed entity (job, alert, etc.)
type varchar(20) topup, hold, deduct, refund
amount int Signed: positive for topup/refund, negative for hold/deduct
balance_after int Cached for cheap balance reads
source varchar(60) woocommerce, pmpro, manual, stripe, etc.
external_id varchar(120) Order/transaction ID at the source - used for idempotency
created_at datetime
actor_id bigint(20) The admin user for manual rows
meta longtext (JSON) Free-form context

Idempotency: (slug, source, external_id, type) is a unique constraint. Duplicate webhook deliveries can't double-credit.

To query the ledger:

$rows = \Wbcom\Credits\Ledger::query( array(
    'slug'    => 'wp-career-board',
    'user_id' => $user_id,
    'limit'   => 50,
));

$balance = \Wbcom\Credits\Credits::get_balance( 'wp-career-board', $user_id );

Never INSERT/UPDATE the ledger directly - use Credits::topup(), Credits::hold(), Credits::deduct(), Credits::refund(). The helpers handle idempotency, audit metadata, and the wcbp_credit_* event hooks.

Where to read further

  • vendor/wbcom-credits-sdk/src/ - the SDK source (vendored, not loaded over the network).
  • audit/journeys/security/license-required-for-pro-rest.md - contract that gates credit-purchase endpoints on license validity.
  • Pro hooks for credits in 03-hooks-reference.md: wcbp_credit_consumed, wcbp_credit_hold_reconciled, wcbp_consumer_cost.

WP Career Board Pro - Shortcode Reference

Every frontend block in Pro ships as a shortcode so site owners can drop them into Elementor / Beaver / Bricks / Divi / classic editor / theme template hooks without leaving their page-builder surface. Same attribute-forwarding contract as Free - see wp-career-board/docs/SHORTCODES.md for the casting rules.

Pro requires the Free plugin. Pro shortcodes only register when the Free plugin is loaded and a valid Pro license is active.


All Pro shortcodes (1.1.0 - full block-to-shortcode coverage)

Shortcode Block Common attributes
[wcbp_resume_form_simple] wcb/resume-form-simple (see detailed section below)
[wcbp_resume_archive] wcb/resume-archive perPage, boardId, orderBy
[wcbp_resume_search_hero] wcb/resume-search-hero headline, subheadline, bgImage
[wcbp_resume_builder] wcb/resume-builder (auto-scoped to current candidate)
[wcbp_resume_single] wcb/resume-single resumeId (override post context)
[wcbp_resume_map] wcb/resume-map boardId, radius, centerLat, centerLng
[wcbp_credit_balance] wcb/credit-balance showHistory, showBuyButton
[wcbp_job_alerts] wcb/job-alerts mode (subscribe|manage)
[wcbp_job_map] wcb/job-map boardId, radius, centerLat, centerLng
[wcbp_application_kanban] wcb/application-kanban jobId (required)
[wcbp_my_applications] wcb/my-applications (auto-scoped to current candidate)
[wcbp_open_to_work] wcb/open-to-work (renders the toggle for the current user)
[wcbp_board_switcher] wcb/board-switcher style (select|tabs|pills)
[wcbp_featured_candidates] wcb/featured-candidates limit, boardId, showSkills
[wcbp_featured_companies] wcb/featured-companies limit, showJobCount
[wcbp_ai_chat_search] wcb/ai-chat-search placeholder, boardId

Numeric strings cast to int, "true"/"false" cast to bool, every- thing else stays a string. So [wcbp_application_kanban jobId="123"] produces the same output as the block with {jobId: 123}.


[wcbp_resume_form_simple] - Quick Profile Form

Single-page sibling of the multi-section resume builder. Captures the high-signal profile fields on one screen so candidates can complete a useful profile in 60 seconds and apply to jobs straight away.

Captures: headline, summary, top skills, years of experience, location, open-to-work toggle, and profile photo.

Attributes

Name Type Default What it does
showPhotoField bool true Show the profile-photo upload. Set false for sidebar embeds.
compact bool false Dense layout (smaller paddings) for sidebar embeds.

Examples

[wcbp_resume_form_simple]
[wcbp_resume_form_simple showPhotoField="false" compact="true"]

Hooks

  • wcb_resume_form_fields - declarative custom-field schema (shared with the multi-section resume builder).
  • wcb_resume_form_simple_initial_state - extend the Interactivity API state.
  • wcb_resume_form_simple_extra_fields - render custom inputs after the built-in fields.

When to use this vs. the multi-section builder

  • Multi-section builder - best on the dedicated "Edit My Resume" page. Long-form, broken into 7 sections (summary, experience, education, skills, certifications, languages, portfolio), good for completeness.
  • Single-page ([wcbp_resume_form_simple]) - best at the moment of signup, in modals over job-listing pages, in onboarding flows, on partner-site embeds. Optimised for "good enough to apply", not completeness.

[wcbp_resume_archive] - Find Candidates

Public "Find Candidates" listing page. Displays avatar, name, headline, top skills, location, and an Open-to-work badge for every publicly visible resume.

Mirrors the chip-bar / sort / search pattern of the Free [wcb_job_listings] block, so candidate search and job search feel identical.

Attributes

Name Type Default What it does
perPage int 12 Page size for the resume grid.
authorId int 0 Limit to a single candidate (pre-filtered embed).
includePrivate bool false Include resumes the candidate has marked private. Only respected for users with the wcbp_view_all_resumes ability.

Examples

[wcbp_resume_archive]
[wcbp_resume_archive perPage="9"]
[wcbp_resume_archive perPage="6" authorId="42"]

[wcbp_credit_balance] - Employer Credit Balance

Employer-facing card showing the current credit balance, a "Buy Credits" button (links to the configured purchase URL - WooCommerce, PMPro, or MemberPress), and an optional recent-transaction history.

Renders nothing for users without the wcb_post_jobs ability.

Attributes

Name Type Default What it does
showHistory bool true Show the recent-transaction list under the balance.
historyCount int 5 How many history rows to show when showHistory is true.

Examples

[wcbp_credit_balance]
[wcbp_credit_balance showHistory="false"]
[wcbp_credit_balance historyCount="10"]

[wcbp_job_alerts] - Job Alerts Subscription

Renders the "Subscribe to alerts for these filters" form when placed above/below a job-listings block - picks up the active filters from the shared Interactivity store. Below the form, lists the candidate's active alerts with a frequency picker (instant / daily) and a delete control.

Renders nothing for logged-out users (links to the registration form).

Attributes

This shortcode takes no attributes today.

Examples

[wcbp_job_alerts]

Existing Pro blocks (no shortcode)

These Pro blocks are inserter-only in 1.1.0 (they're typically reached via the dashboards that already host them):

  • wcb/application-kanban - ATS-style application pipeline (admin / employer dashboard).
  • wcb/featured-candidates - homepage strip of featured candidates.
  • wcb/featured-companies - homepage strip of featured companies.
  • wcb/my-applications - candidate's own applications list.
  • wcb/open-to-work - toggle pill for the candidate dashboard.
  • wcb/resume-builder - multi-section resume builder.
  • wcb/resume-search-hero - search hero above the resume archive.
  • wcb/resume-single - single-resume public view.

If you need any of these as a shortcode, file an issue - adding one is a two-line change to register_shortcodes().


Shortcode attributes - what gets cast where

Same contract as the Free plugin. See wp-career-board/docs/SHORTCODES.md.

WP Career Board Pro - Hook Reference

Pro extends Free's hook surface. Most theme integrators will only need the shared wcb_* family documented in wp-career-board/docs/HOOKS.md - those filters work the same whether the form is in Free or Pro.

This document covers Pro-only hooks (wcbp_*). They power Pro's internal modules (credits, resumes, alerts, AI, kanban) and may change between Pro releases - prefer wcb_* hooks where possible.

Pro-side form-field filters

Resume Builder + Resume Form Simple both read the shared wcb_resume_form_fields filter (see the Free hooks doc for the schema). That's the recommended way to add custom resume fields - one filter declaration covers both forms.

If you specifically need Pro-only behaviour:

Filter Purpose
wcb_resume_form_fields (shared with Free family) Declarative custom fields for resume-builder + resume-form-simple
wcb_resume_form_initial_state Pre-load Interactivity state on resume-builder
wcb_resume_form_simple_initial_state Pre-load state on resume-form-simple
wcbp_resume_primary_fields Override the 1-2 fields shown in the compact card view per resume section (Pro-internal)

Credits SDK consumer cost

Pro registers two consumers with the Wbcom Credits SDK: job_post and featured_upgrade. Tier-aware pricing hooks the shared wcbp_consumer_cost filter:

add_filter( 'wcbp_consumer_cost',
    function( $cost, $user_id, $item_id, $board_id, $consumer ) {
        if ( 'featured_upgrade' === $consumer && my_theme_user_is_premium( $user_id ) ) {
            return 0; // free for premium members
        }
        return $cost;
    }, 10, 5
);

The BpTieredCreditCost integration already hooks this filter to read the wcbp_credit_cost_matrix option (BP member type / PMPro level / MemberPress membership rules) - your filter runs alongside.

Lifecycle actions

Action Args When fired
wcb_featured_upgrade_requested (int $job_id, int $user_id) Hold credits for an upgrade
wcb_featured_upgrade_completed (int $job_id, int $user_id) Deduct credits, set _wcb_featured
wcb_featured_upgrade_failed (int $job_id, int $user_id, string $reason) Refund credits
wcbp_credits_topped_up (int $user_id, int $amount, string $source) Credits added
wcbp_credits_low (int $user_id, int $balance) Balance below threshold
wcbp_send_alert_email (int $alert_id, int $user_id, array $matches) Job-alert digest
wcbp_resume_published (1.1.0) (int $post_id, WP_Post $post) Resume transitions to publish status
wcbp_field_value_saved (1.1.0) (int $post_id, string $field_key, mixed $value) Custom field value persisted
wcbp_credit_consumed (1.1.0) (int $user_id, int $amount, int $item_id) Credit deduction committed (mirrors SDK's wbcom_credits_deducted under the Pro namespace)

Extension surface for addons (1.1.0)

Filters that let addon vendors plug into Pro the same way Pro plugs into Free.

Filter Args Purpose
wcbp_ai_provider_drivers (array $registry, string $api_key, string $base_url) Map of provider_slug => factory_callable. Add Cohere / Mistral / vLLM / etc. without touching the AI module's match.
wcbp_alert_dispatch_channels (array $channels) Map of channel_slug => callable($alert, $job_ids). Default is email (which fires wcbp_send_alert_email); addons add Slack / Discord / SMS / push.
wcbp_resume_pdf_renderer (callable|null $renderer, int $post_id) Return a callable accepting ($html, $post_id) to swap DomPDF for mPDF / Prince / a service.
wcbp_kanban_card_columns (array $columns, int $job_id) Mutate the Kanban column array before /jobs/(id)/kanban returns it - add archived / on-hold columns or annotate existing ones.
// Example: register a 4th AI provider via the wcbp_ai_provider_drivers filter.
add_filter( 'wcbp_ai_provider_drivers', function ( array $registry, string $api_key ): array {
	$registry['mistral'] = static fn() => new My\Addon\MistralDriver( $api_key );
	return $registry;
}, 10, 2 );

REST response filters (wcb_rest_prepare_*)

Pro extends the canonical wcb_rest_prepare_* pattern that Free established (see Free hook reference - REST response filters). Each prepared Pro resource fires a sibling filter so addons can decorate responses without touching Pro internals.

Filter Resource Args Purpose
wcb_rest_prepare_resume Resume (array $data, WP_Post|null $resume, WP_REST_Request $request, string $context) Decorate the prepared resume response. context is single, list, archive (public archive), create, save, or pdf_replace.
wcb_rest_prepare_board Board (array $data, WP_Post $board, WP_REST_Request $request) Decorate the prepared board response (GET /boards/{id}).
wcb_rest_prepare_board_stage Board stage (array $stage, WP_REST_Request $request) Decorate each prepared stage row in GET /boards/{id}/stages.
wcb_rest_prepare_notification Notification (array $data, object $row) Decorate each prepared notifications-bell row.

Example - flag the candidate's primary resume in the dashboard list:

add_filter( 'wcb_rest_prepare_resume', function ( array $data, $resume, $request, string $context ): array {
    if ( 'list' !== $context || ! $resume instanceof WP_Post ) {
        return $data;
    }
    $data['is_primary'] = (bool) get_post_meta( $resume->ID, '_my_primary_resume', true );
    return $data;
}, 10, 4 );

REST endpoints

Pro adds the following endpoints under wcb/v1/:

  • GET/POST /alerts, GET/PUT/DELETE /alerts/(id)
  • POST /ai/match, GET /candidates/(id)/matches, GET /ai/ranked-applications/(job_id), POST /jobs/ai-description
  • PUT /applications/(id)/stage, GET /jobs/(id)/kanban
  • GET /credits/packages, GET /employers/(id)/credits
  • GET/POST /fields/groups, GET/PUT/DELETE /fields/groups/(id), GET/POST /fields/groups/(group_id)/fields, GET/PUT/DELETE /fields/(id), POST /fields/reorder
  • GET /geocode
  • GET/PUT /boards/(id), GET/POST /boards/(id)/stages, PUT/DELETE /boards/(id)/stages/(stage_id)
  • GET/POST /resumes, GET /candidates/(id)/resumes, GET/PUT/DELETE /resumes/(id), GET /resumes/(id)/pdf
  • GET /notifications, POST /notifications/(id)/read, POST /notifications/read-all

Same permission_callback pattern as Free - abilities API only, no current_user_can('manage_options') fallbacks.

BuddyPress integrations

Pro adds these BP-specific extension points:

Hook Purpose
wcbp_bp_profile_tab (option, not hook) Toggle the candidate/employer profile tabs
wcb_moderate_jobs_ability_check (shared) Grant moderation rights for a specific job; BpGroupBoards uses this to give group admins moderation rights for jobs on their group's board

Convention

  • wcb_* - customer-facing extension surface, shared with Free. Stable.
  • wcbp_* - Pro-internal hooks. May change between Pro releases.

When extending a form, prefer the shared wcb_* family unless you specifically need a Pro-internal behaviour.

For the field-group schema and form-fields filter list, see Free hook reference.

REST controller carve-outs

Pro endpoints extend WCB\Pro\Api\Pro_REST_Controller and ship as classes under WCB\Pro\Api\Endpoints\, registered through the central register_rest_routes() loop in core/class-pro-plugin.php.

One Pro class carves out: admin/class-pro-setup-wizard.php (lines 167, 184, 206) registers /wizard/activate-license, /wizard/setup-credits, and /wizard/create-pro-pages directly via register_rest_route(). It still extends WCB\Api\RestController, but its routes live with the admin wizard rather than in api/endpoints/ because they're step handlers for that wizard.

The full carve-out rationale and the matching Free exceptions (setup wizard + moderation module) are documented in Free hook reference - REST controller carve-outs. New Pro routes should still ship as Endpoint classes.

Something unclear? Open a support ticket →

Buy WP Career Board Pro