Wbcom Designs WB Gamification Docs
Back to product Buy Now

Getting Started

Installation, setup wizard, and first steps

Installation

Requirements

Before installing WB Gamification, confirm your environment meets these minimums:

  • WordPress 6.4 or higher
  • PHP 8.1 or higher
  • MySQL 5.7 or MariaDB 10.3 or higher

BuddyPress is optional. The plugin works on any standard WordPress site and automatically activates BuddyPress-specific features when BuddyPress is detected.

Installing the Plugin

From the WordPress admin:

  1. Go to Plugins > Add New Plugin.
  2. Search for WB Gamification.
  3. Click Install Now, then Activate.

Manual upload:

  1. Download the plugin ZIP file.
  2. Go to Plugins > Add New Plugin > Upload Plugin.
  3. Choose the ZIP file and click Install Now.
  4. Click Activate Plugin.

What Happens on Activation

When you activate WB Gamification, the plugin does the following automatically:

  • Creates 20 custom database tables to store events, points, badges, levels, challenges, streaks, kudos, leaderboard snapshots, member preferences, and more.
  • Seeds your site with 5 default levels (Newcomer, Member, Contributor, Regular, Champion) and 30 default badges.
  • Registers all gamification actions appropriate for your active plugins. If BuddyPress is active, BuddyPress triggers load automatically.
  • Redirects you to the Setup Wizard so you can choose a starter template.

You do not need to configure anything manually. The plugin detects your active plugins and loads the right point-earning actions automatically.

After Activation

You are redirected to the Setup Wizard. Choose a starter template that matches your site type - this takes about one minute. After completing the wizard, your site is fully configured and ready for members to start earning points.

If you skip the wizard, default point values are used. You can always return to Gamification > Settings to adjust them.

Multisite

WB Gamification can be activated per-site on a WordPress multisite network. Network-wide activation is not recommended because each site maintains its own gamification data and settings independently.

Setup Wizard

The Setup Wizard appears automatically the first time you activate WB Gamification. It takes about one minute to complete and pre-configures point values for your site type so you are not starting from a blank slate.

Choosing a Starter Template

The wizard presents five templates. Pick the one that best describes your site.

Blog / Publisher

Best for standalone WordPress blogs without BuddyPress. Rewards writing quality content and meaningful comments.

Point values configured:

  • Publish a blog post - 25 points
  • Publish your first post ever - 20 points (one-time bonus)
  • Leave a comment - 5 points
  • Your post receives a comment - 3 points

Leaderboard defaults to monthly period.

Community Engagement

Best for BuddyPress-powered communities. Rewards social participation - posting, reacting, connecting, and giving kudos. Requires BuddyPress.

Point values configured:

  • Post an activity update - 10 points
  • Comment on an activity - 5 points
  • Accept a friendship - 8 points
  • Join a group - 8 points
  • Receive a reaction - 3 points
  • Give kudos - 2 points
  • Receive kudos - 5 points

Leaderboard defaults to weekly period.

Online Course

Best for LearnDash-powered course sites. Heavy on course completion and academic progress with credential badges.

Point values configured:

  • Complete a lesson - 20 points
  • Complete a course - 100 points
  • Pass a quiz - 30 points
  • Publish first post - 10 points

Leaderboard defaults to cohort mode so learners compete within their enrollment group.

Coaching Platform

Best for private coaching or accountability communities where members should not compete directly against each other. Leaderboard is private by default - members see their own progress, not a public ranking.

Point values configured:

  • Check in - 15 points
  • Complete a goal - 50 points
  • Publish first post - 10 points

Leaderboard defaults to private mode.

Nonprofit / Mission

Best for volunteer-driven or mission-aligned communities. Uses team leaderboards only so the focus stays on collective impact rather than individual competition.

Point values configured:

  • Log volunteer hours - 30 points
  • Post an activity update - 5 points
  • Join a group - 10 points

Leaderboard defaults to team-only mode.

Skipping the Wizard

If you want to configure everything manually, scroll to the bottom of the wizard page and click Skip setup. Default point values will be used. You can return to Gamification > Settings at any time to adjust point values, leaderboard periods, and all other options.

After Completing the Wizard

After you select a template, the wizard:

  1. Saves the chosen point values to your settings.
  2. Sets the leaderboard default period for your template.
  3. Redirects you to the main Gamification dashboard with a "Setup complete" confirmation.

Changing Settings Later

Nothing the wizard configures is permanent. All point values, leaderboard modes, and other options can be changed at any time in Gamification > Settings. You can also re-run individual pieces of configuration without re-running the full wizard.

Quick Start Guide

Get WB Gamification running in five minutes. This guide shows you the complete loop from activation to your first member earning points.

Step 1: Activate and Run the Wizard (2 minutes)

  1. Activate the plugin from Plugins > Installed Plugins.
  2. The Setup Wizard opens automatically.
  3. Click the template that matches your site. For a BuddyPress community, choose Community Engagement. For a blog, choose Blog / Publisher.
  4. Click Use This Template.

The wizard saves your point values and redirects you to the Gamification dashboard.

Step 2: Check What Is Already Working (30 seconds)

Go to Gamification > Settings. You will see every action that is currently active on your site - things like "Post an activity update," "Join a group," and "Complete a course." These are already wired up. No additional configuration is needed.

Step 3: Have a Member Do Something (1 minute)

Log in as a regular member. Do one of the active actions - for example, post an activity update on a BuddyPress community page, or leave a comment on a blog post.

Within a few seconds, a toast notification appears in the bottom-right corner showing how many points were earned.

Step 4: Check the Member's Points (30 seconds)

Points appear immediately in three places:

  • The member-points block on any page where you have placed it
  • The member's BuddyPress profile under the Gamification tab (if BuddyPress is active)
  • Gamification > Members in the admin, where you can view any member's full point history

Step 5: View the Analytics Dashboard (30 seconds)

Go to Gamification > Analytics. You will see KPI cards showing total points awarded, active members, badges earned, and more. The dashboard refreshes every 10 minutes.

What Happens Automatically

From here, the plugin handles everything on its own:

  • Members earn points as they take actions
  • Badges award automatically when members meet the conditions
  • Levels advance when members cross point thresholds
  • Streaks build each day a member is active
  • The leaderboard updates on a rolling basis

You do not need to do anything to keep it running. Explore Gamification > Badges, Levels, and Challenges to customize the experience for your community.

Free vs Pro

WB Gamification is a complete gamification system in the free version. Pro adds competitive league mechanics, automation tools, and advanced engagement features.

Feature Comparison

Feature Free Pro
Points engine Yes Yes
30 default badges + custom badges Yes Yes
5 default levels + custom levels Yes Yes
Leaderboard (all-time, monthly, weekly, daily) Yes Yes
Individual challenges Yes Yes
Activity streaks with milestones Yes Yes
Peer kudos Yes Yes
17 Gutenberg blocks Yes Yes
11 shortcodes Yes Yes
38 REST API endpoints Yes Yes
9 plugin integrations (WP, BP, WooCommerce, LearnDash, bbPress, LifterLMS, MemberPress, GiveWP, The Events Calendar) Yes Yes
BuddyPress profiles, directory, activity feed Yes Yes
Toast notifications Yes Yes
GDPR export and erasure Yes Yes
WP-CLI commands Yes Yes
Admin analytics dashboard Yes Yes
Manual point awards Yes Yes
Rank automation rules Yes Yes
Cohort leagues (Duolingo-style weekly competition, promotion/demotion) No Yes
Community challenges (team goals with shared progress bar) No Yes
Redemption store (spend points on rewards, coupons, or custom items) No Yes
Badge sharing pages (public OG-ready URLs, LinkedIn sharing) No Yes
OpenBadges 3.0 credential issuance No Yes
Outbound webhooks (HMAC-signed, Zapier / Make / n8n) No Yes
Weekly recap emails No Yes
Leaderboard nudge emails No Yes
Profile cosmetics and frames No Yes
Tenure badges (member anniversary milestones) No Yes
Site-first badges (first member to complete an action) No Yes
Status retention engine No Yes
API key authentication (cross-site gamification center) No Yes

What the Free Version Covers

The free version includes the complete point-earning pipeline, every display block, the full REST API, and all core engagement mechanics. Most WordPress and BuddyPress communities will find everything they need without upgrading.

The 9 bundled integrations cover the most common plugin stacks. BuddyPress, WooCommerce, and LearnDash integrations load automatically when those plugins are detected - no extra configuration needed.

What Pro Adds

Pro features focus on competition, automation, and retention:

Cohort leagues put members into weekly competition groups with promotion and demotion, similar to how Duolingo manages leagues. This keeps competition fresh without the same top members dominating every week.

Community challenges set site-wide goals. Every member's action contributes to a shared progress bar. When the community hits the target, everyone who contributed earns bonus points.

Redemption store lets members spend their points on rewards you define - discount coupons, digital downloads, access to content, or any custom reward type.

Webhooks let you connect WB Gamification to any external tool. Every point award, badge earn, and level-up can trigger a Zapier workflow, Make scenario, or n8n automation.

Weekly emails automatically send each member a summary of their activity, rank movement, and upcoming challenge deadlines - without you doing anything.

How WB Gamification Works

Understanding how the plugin processes activity helps you configure it well and troubleshoot when something unexpected happens.

The Core Idea: Events In, Rules Evaluate, Effects Out

Every time a member does something on your site - publishes a post, comments, completes a course, joins a group - WB Gamification sees it as an event. The engine takes that event, checks its rules, and produces effects like points, badges, and notifications.

The source of the event does not matter to the engine. A WooCommerce purchase, a LearnDash lesson completion, and a BuddyPress activity post all arrive as the same type of object. This is why one plugin can handle so many different site types without add-ons.

The Flow, Step by Step

Here is what happens each time a member takes an action:

1. Action detected A member does something that has a registered gamification trigger - for example, they post an activity update on BuddyPress. WordPress fires the bp_activity_posted_update hook.

2. Event created WB Gamification catches that hook and creates a standardized event record. The record stores: which user, which action, a timestamp, and any relevant metadata (like the word count of a post, which helps with quality-weighted scoring).

3. Points awarded The engine looks up how many points this action is worth (from your settings). It adds a row to the immutable points ledger. This ledger is the permanent record - all other data is derived from it.

4. Badge conditions checked After points are saved, the BadgeEngine checks every active badge condition to see if this member now qualifies. Badge conditions include things like "earned 100 cumulative points" or "published 10 posts." If a condition is met and the member does not already have the badge, it awards immediately.

5. Level checked The LevelEngine compares the member's new cumulative points against your level thresholds. If they have crossed into a new level, it updates their level and fires a level-up notification.

6. Streak updated The StreakEngine records that this member was active today. If today is consecutive with their last active day (within the grace period), their streak counter increases. If they hit a streak milestone (7, 14, 30, 60, 100, 180, or 365 days), they earn bonus points and see a milestone notification.

7. Challenge progress updated If any active challenge involves this action, the ChallengeEngine increments the member's progress counter. If they reach the target, the challenge completes and bonus points are awarded.

8. Notification sent The NotificationBridge collects all the events from this request - points, badge, level-up, streak milestone, challenge completion - and outputs them as toast notifications in the bottom-right corner of the page. BuddyPress notifications are also created if BuddyPress is active.

9. Activity feed updated (if BuddyPress is active) Significant events like earning a badge, levelling up, or receiving kudos are posted to the BuddyPress activity stream so the community can see them.

Rules Are Stored as Data, Not Code

One key design decision: all badge conditions, point values, and level thresholds are stored in your database. This means you can change any rule from the admin settings without writing PHP or editing files. It also means the rules can be read and updated via the REST API.

Auto-Detection of Active Plugins

WB Gamification scans your active plugins on each page load and loads only the integration manifests that are relevant. If WooCommerce is not installed, WooCommerce triggers are never registered. If you later add WooCommerce, the triggers activate automatically - no reconfiguration needed.

Processing Is Asynchronous

Some point awards - particularly high-traffic ones like activity updates - are processed asynchronously using Action Scheduler. This means the member's action completes immediately without waiting for the gamification pipeline to finish. Points and badges may appear a few seconds after the action rather than instantly.

Features

Core gamification features — points, badges, levels, and more

Points

Points are the core currency of WB Gamification. Every action a member takes that the plugin is configured to track results in points being added to their permanent point total.

What Points Are

A member's point total is the sum of every point award they have ever received. Points never expire and never decrease (unless you manually adjust them). The total drives badge unlocks, level progression, leaderboard ranking, and challenge completion.

How Members Earn Points

Points are awarded automatically. The moment a member completes a tracked action, points are added to their account. No member needs to claim points or do anything special to receive them.

The plugin tracks actions from your active plugins automatically. Below are the default point values by category.

WordPress Actions

Action Default Points Repeatable
Join the site (register) 15 No
First login 10 No
Complete WordPress profile (add bio) 10 No
Post receives a comment 3 Yes
Publish a blog post 25 Yes
Publish first post ever 20 No
Leave a comment 5 Yes
Comment approved from moderation 5 Yes

Note: The publish and comment actions in the WordPress category are only active when BuddyPress is not installed. When BuddyPress is active, the BuddyPress manifest covers those same actions.

BuddyPress Actions

Action Default Points Repeatable
Post an activity update 10 Yes
Comment on an activity 5 Yes
Accept a friendship 8 Yes
Join a group 8 Yes
Create a group 20 Yes
Complete extended profile 15 No
Receive a reaction 3 Yes
Create a poll 10 Yes
Publish a member blog post 25 Yes
Upload media 5 Yes

WooCommerce Actions

Action Default Points Repeatable
Complete a purchase 25 Yes
Complete first purchase ever 50 No
Leave a product review 15 Yes
Add a product to wishlist (YITH) 5 Yes

LearnDash Actions

Action Default Points Repeatable
Complete a course 100 Yes
Complete a lesson 15 Yes
Complete a topic 5 Yes
Pass a quiz 25 Yes
Assignment approved by instructor 20 Yes

Additional integrations are available for bbPress, LifterLMS, MemberPress, GiveWP, and The Events Calendar.

Changing Point Values

Go to Gamification > Settings and find the Points section. Every active action is listed with its current point value. Click the value field, enter a new number, and save.

Setting a value to 0 effectively disables point awards for that action without disabling the action itself (badge and challenge tracking still fires).

Where Members See Their Points

Members can see their points in several places:

  • BuddyPress profile - the Gamification tab shows total points, current level, and recent activity (requires BuddyPress)
  • Member Points block - place this Gutenberg block on any page; it shows the logged-in member's total, level name, and progress bar toward the next level
  • Leaderboard - members can see their rank relative to others

Viewing the Earning Guide

The Earning Guide block and shortcode ([wb_gam_earning_guide]) displays a formatted list of every active point-earning action with its point value. Add this to a "How to earn points" page to help members understand what actions are worth taking.

Manual Point Awards

Admins can award or adjust points manually. Go to Gamification > Manual Award, select a member, enter a point amount and reason, and click Award Points. The award is logged in the member's point history with the reason you entered.

Manual awards show up in point history the same way as automatic awards.

Points History

Every point transaction is permanently logged. Members can see their full earning history in the Points History block ([wb_gam_points_history]), which shows the action, points earned, and date for each transaction.

Badges

Badges are visual achievements members earn by hitting specific milestones. The plugin ships with 30 default badges and supports unlimited custom badges.

What Badges Are

A badge is a named achievement with an image, description, and one or more conditions that must be met before it awards. Badges award automatically the moment a member meets all conditions. Members keep their badges permanently unless the badge has an expiry period.

Default Badges

The 30 default badges are organized into categories:

Points Milestones

Badges for reaching cumulative point totals. Examples: "First Steps" (100 points), "Rising Star" (500 points), "Community Pillar" (1,500 points), "Champion" (5,000 points).

WordPress Actions

Badges for WordPress-native contributions. Examples: "Published Author" (publish first post), "Prolific Writer" (publish 10 posts), "Commenter" (leave first comment), "Conversation Starter" (post receives a comment).

BuddyPress Actions

Badges for BuddyPress community participation. Examples: "Welcome Aboard" (complete extended profile), "Social Butterfly" (accept 10 friendships), "Group Builder" (create a group), "Reaction Magnet" (receive 50 reactions).

Special

Badges assigned manually by admins or awarded for extraordinary contributions. These do not auto-evaluate - they are given by an admin through the Manual Award interface.

How Badges Are Awarded

Auto-award happens automatically. After every point transaction, the badge engine evaluates all active badge conditions for the member who just earned points. If any condition is now satisfied for the first time, the badge awards immediately.

Conditions that trigger auto-award:

  • Point milestone - member's cumulative points reach a threshold
  • Action count - member has completed a specific action a set number of times

Manual award is done by an admin. Go to Gamification > Manual Award, select a member, choose a badge from the list, and click Award. The member receives a notification right away.

Creating Custom Badges

  1. Go to Gamification > Badges.
  2. Click Add New Badge.
  3. Enter a name, description, and choose or upload a badge image.
  4. Under Award Condition, choose the condition type:
    • Point milestone - enter the cumulative points required
    • Action count - choose the action and the number of times it must be completed
    • Admin only - the badge is never awarded automatically
  5. Optionally configure advanced options (see below).
  6. Click Save Badge.

The new badge is active immediately. Existing members who already meet the condition will not receive it retroactively - it awards only on future transactions.

Badge Images

Each badge displays an image in blocks and on BuddyPress profiles. When you create a custom badge, you can upload any image from your WordPress Media Library. Recommended size is 200x200 pixels. PNG files with transparent backgrounds work best.

Default badges use SVG icons that scale cleanly at any size.

Advanced Badge Options

When creating or editing a badge, you can set the following optional limits:

Expiry (validity_days) - If set, the badge expires this many days after it is earned. An expired badge is removed from the member's showcase. Useful for certifications that need periodic renewal. Leave blank for permanent badges.

Close date (closes_at) - The badge stops awarding after this date. Members who earn it before the date keep it permanently. Useful for event-based or seasonal badges.

Maximum earners (max_earners) - The badge stops awarding once this many members have earned it. Useful for "first 100 members" exclusivity badges.

Credential Badges (OpenBadges 3.0)

Badges marked as Credential badges generate a verifiable digital credential following the OpenBadges 3.0 standard. Members can download the credential JSON file, share it on LinkedIn, or include it in a digital portfolio to prove they earned the badge on your site.

This feature is part of WB Gamification Pro.

Viewing Badges

Members can see their earned badges in:

  • The Badge Showcase block on any page ([wb_gam_badge_showcase])
  • Their BuddyPress profile Gamification tab (if BuddyPress is active)

Use the show_locked="1" attribute on the Badge Showcase shortcode to display unearned badges grayed out, so members know what they are working toward.

Levels

Levels give members a visible sense of status and long-term progression. As members accumulate points, they advance through a sequence of levels - each with a name, a threshold, and an optional icon.

Default Levels

Five levels are created automatically on activation:

Level Minimum Points
Newcomer 0
Member 100
Contributor 500
Regular 1,500
Champion 5,000

Every member starts as a Newcomer. As they earn points, they advance through the ladder automatically.

How Progression Works

Level state is calculated from the member's total points. After every point award, the plugin compares the member's new total against all level thresholds. If the new total puts them in a higher level, the level is updated immediately.

Level is never stored independently - it is always derived from the points ledger. This means if you change a level threshold, member levels update automatically on their next point award.

Level-Up Notifications

When a member advances to a new level, they receive:

  • A toast notification in the bottom-right corner of the page with the new level name and icon
  • A BuddyPress notification (if BuddyPress is active)
  • An activity feed post announcing the level-up to the community (if BuddyPress is active)

Progress Bar

The Level Progress block and the Member Points block both display a visual progress bar showing how far the member is toward the next level. The bar updates in real time after each page load.

Members can also see their current level name and the points needed for the next level.

Adding Custom Levels

  1. Go to Gamification > Levels.
  2. Click Add New Level.
  3. Enter a level name (for example, "Expert" or "Ambassador").
  4. Enter the minimum points required to reach this level.
  5. Optionally upload a level icon image.
  6. Click Save.

Levels are always sorted by their minimum points threshold. You can add as many levels as your community needs.

Tips for setting thresholds:

  • Think about how many points a typical active member earns per week
  • Space levels so members advance roughly every 2-4 weeks of active participation
  • Reserve your highest level for genuinely long-term members - it loses meaning if everyone reaches it quickly

Editing and Removing Levels

You can rename any level or change its point threshold at any time. Changes take effect immediately. Members who have already passed the new threshold stay at that level; members who are below it will drop to the appropriate lower level on their next page load.

You can remove custom levels, but you cannot remove the five default levels. To effectively disable a default level, raise its threshold very high so it is unreachable.

Displaying Levels

Level information appears in:

  • The Level Progress block - shows current level name, icon, progress bar, and points needed for next level ([wb_gam_level_progress])
  • The Member Points block - shows total points, current level name, and progress bar ([wb_gam_member_points])
  • BuddyPress profiles - the Gamification tab shows current level (if BuddyPress is active)
  • Top Members block - optionally shows each member's level label beneath their name ([wb_gam_top_members show_level="1"])

Leaderboard

The leaderboard ranks members by points earned over a selected time period. It updates automatically and can be embedded on any page.

Time Periods

The leaderboard supports four time periods:

Period What It Shows
All-time Total points since the member joined
Monthly Points earned in the current calendar month
Weekly Points earned in the current calendar week (Monday to Sunday)
Daily Points earned today

Each period is a separate leaderboard snapshot. Members who are active today appear on the daily leaderboard even if they rank lower on the all-time board.

Group Scoping

When BuddyPress is active, you can scope the leaderboard to a single BuddyPress group. Members outside that group are excluded from the ranking. This lets you create group-specific leaderboards for course cohorts, team challenges, or private communities.

To scope a leaderboard to a group, set scope_type="group" and scope_id to the BuddyPress group ID in the block settings or shortcode.

How Rankings Are Calculated

Leaderboard positions are calculated from the points ledger and stored in a snapshot cache. The cache is refreshed automatically on a schedule. This means:

  • Very recent activity may take a short time to appear on the leaderboard
  • Page loads are fast because the ranking query runs against the cached snapshot rather than recounting points from scratch

If you award points manually and need the leaderboard to update immediately, you can clear the snapshot cache from Gamification > Settings.

The "Your Rank" Section

When a logged-in member views the leaderboard, the block highlights their current rank below the top list even if they are not in the visible top section. This way every member can see where they stand regardless of their position.

Member Opt-Out

Members can opt out of appearing on the leaderboard from their notification preferences. An opted-out member is excluded from all leaderboard snapshots. Admins cannot override a member's opt-out choice.

See the Privacy documentation for more details on how to access preference settings.

Adding the Leaderboard to a Page

Using the Gutenberg block:

  1. Edit any page.
  2. Click the block inserter (+) and search for WB Gamification Leaderboard.
  3. Add the block. Use the sidebar panel to set the period, limit, and group scope.
  4. Publish or update the page.

Using a shortcode:

[wb_gam_leaderboard period="week" limit="10"]
[wb_gam_leaderboard period="all" limit="20" scope_type="group" scope_id="5"]

Available period values: all, month, week, day

Top Members Block

For a compact podium-style display of the top 3 members, use the Top Members block instead. It shows avatars in a visual podium layout and is well-suited for homepage sections or sidebars.

[wb_gam_top_members limit="3" layout="podium"]
[wb_gam_top_members limit="5" layout="list" show_badges="1"]

Challenges

Challenges give members a specific goal to work toward, with a bonus point reward for completing it. They are time-bound, trackable, and displayed with a live progress bar.

What a Challenge Is

A challenge asks a member to perform a specific action a set number of times within a defined period. When they hit the target, the challenge completes automatically and bonus points are awarded immediately.

Example challenges:

  • "Post 5 activity updates this week" - 50 bonus points
  • "Leave 10 comments this month" - 75 bonus points
  • "Complete 3 LearnDash lessons" - 100 bonus points

Creating a Challenge

  1. Go to Gamification > Challenges.
  2. Click Add New Challenge.
  3. Fill in the following fields:

Title - The name members see. Make it action-oriented and specific (for example, "Weekend Writer" or "Community Builder").

Action - Choose the action members must perform. The list shows every active gamification trigger on your site.

Target - The number of times the action must be completed.

Bonus Points - Points awarded when the challenge is completed. This is on top of the regular points members earn for each action.

Start Date / End Date - Optional. Leave blank for an always-on challenge. Set dates for seasonal or event-based challenges. Members cannot start a dated challenge before its start date, and it closes automatically after the end date.

Status - Set to Active to make it visible to members. Draft challenges are not shown.

  1. Click Save Challenge.

How Members Track Progress

Members see their challenge progress in the Challenges block or via the shortcode. For each active challenge, they see:

  • The challenge title
  • A progress bar showing completions versus target
  • How many days remain (if the challenge has an end date)
  • A "Completed" badge once they finish

When a challenge completes, the member receives a toast notification and, if BuddyPress is active, a BuddyPress notification.

Completion and Bonus Points

When a member reaches the target count for a challenge, the system:

  1. Marks the challenge as completed for that member
  2. Awards the bonus points immediately
  3. Sends a completion notification
  4. Posts a completion event to the BuddyPress activity stream (if active)

A member who has completed a challenge will not earn the bonus points again for the same challenge, even if they continue performing the action.

Challenge Display

Gutenberg block: Add the WB Gamification Challenges block to any page. The sidebar lets you set how many challenges to show and whether to include completed ones.

Shortcode:

[wb_gam_challenges limit="3"]
[wb_gam_challenges show_completed="0" limit="5"]
Attribute Default Description
limit 0 (all) Maximum number of challenges to show
show_completed 1 Whether to include completed challenges
show_progress_bar 1 Whether to show the progress bar
user_id 0 (current user) Show challenges for a specific user ID

Tips

  • Short-duration challenges (1 week) maintain more urgency than open-ended ones.
  • Set bonus points higher than what a member would earn just from the regular action points - the challenge should feel worth it.
  • Run a new challenge each week or month to give returning members a reason to engage.
  • Use challenges to highlight specific areas: if forum activity is low, create a "bbPress Reply" challenge.

Streaks

Streaks reward members for consistent, ongoing participation. The longer a member stays active day after day, the higher their streak count - and at key milestones, they earn bonus points.

How Streaks Work

A streak counts how many consecutive days a member has been active. "Active" means earning at least one point from any action. Streaks are not tied to logins - the member needs to actually do something.

Streaks are timezone-aware. Midnight is calculated using the member's own timezone setting. If they have not set a timezone, the site timezone is used. This means a member in Tokyo and a member in New York each get a fair day boundary.

The Grace Period

Life happens. The streak engine includes a 1-day grace period by default. This means:

  • If a member misses exactly one day, their streak continues - the grace period covers the gap
  • The grace period can only be used once per streak. Missing two consecutive days breaks the streak.
  • The grace period resets after each consecutive day. If you use it on a Wednesday, you can use it again after a full consecutive sequence.

Admins can adjust the grace period from 0 to 3 days in Gamification > Settings > Streaks.

Streak Milestones

When a member's current streak reaches one of these milestones, they earn a bonus and see a milestone notification:

Milestone Event
7 days Bonus points + toast notification
14 days Bonus points + toast notification
30 days Bonus points + toast notification
60 days Bonus points + toast notification
100 days Bonus points + toast notification
180 days Bonus points + toast notification
365 days Bonus points + toast notification

The number of bonus points awarded at each milestone is configurable in Gamification > Settings > Streaks. Set to 0 to give a notification without bonus points.

What Resets a Streak

A streak resets to 1 when:

  • A member misses more than one consecutive day (beyond the grace period)
  • A member's grace period was already used and they miss another day

When a streak resets, the previous streak length is saved as the member's longest streak record. Members can always work toward beating their personal best.

Displaying Streaks

Gutenberg block: Add the WB Gamification Streak block to any page. It shows the current streak count prominently, plus an optional heatmap of activity over the past 90 days (similar to GitHub's contribution graph).

Shortcode:

[wb_gam_streak]
[wb_gam_streak show_longest="1" show_heatmap="1" heatmap_days="90"]
Attribute Default Description
show_longest 0 Also display the member's longest-ever streak
show_heatmap 0 Show the activity heatmap calendar
heatmap_days 90 How many days the heatmap covers (1-365)
user_id 0 (current user) Show streak for a specific user ID

Tips

  • Add the streak block to the member's profile page or dashboard so they see their streak every time they visit.
  • Set milestone bonus points high enough to feel rewarding. A 30-day streak is a significant commitment and deserves meaningful recognition.
  • Use the heatmap on member profiles to give members a visual record of their activity history.

Kudos

Kudos is a peer-to-peer recognition system. Members can give a shoutout to another member, with both the giver and receiver earning points in the process.

What Kudos Is

Kudos lets members publicly recognize each other for helpful contributions, great content, or community support. A kudos can include a short optional message. Both members earn points when kudos is given - the receiver earns more than the giver, reflecting the value of being recognized.

Default Point Values

Role Default Points
Receiver (member getting kudos) 5 points
Giver (member sending kudos) 2 points

These values are configurable in Gamification > Settings > Kudos.

Daily Send Limit

Each member can give a maximum of 5 kudos per day by default. This prevents gaming the system by members repeatedly sending kudos to the same friend. The limit resets at midnight (site timezone).

When a member reaches their daily limit, the kudos button shows an informative message telling them when the limit resets.

The daily limit is configurable. Go to Gamification > Settings > Kudos and change the Daily Kudos Limit field.

Rules and Restrictions

  • Members cannot give kudos to themselves
  • Kudos can include an optional message of up to 255 characters
  • Both point awards (giver and receiver) flow through the full gamification pipeline - they count toward badge conditions, level thresholds, streaks, and challenges

The Kudos Feed

The Kudos Feed block and shortcode display a public stream of recent kudos activity. Each entry shows the giver's avatar, the receiver's avatar, and the optional message.

This creates a visible culture of recognition. When members see others being recognized, they are more likely to send kudos themselves.

Shortcode:

[wb_gam_kudos_feed limit="10"]
[wb_gam_kudos_feed limit="5" show_messages="0"]
Attribute Default Description
limit 10 How many recent kudos to show (max 50)
show_messages 1 Whether to display the kudos message

BuddyPress Integration

When BuddyPress is active:

  • Giving kudos creates a BuddyPress activity post so the community can see it
  • The receiver gets a BuddyPress notification
  • The Kudos Feed block pulls from the same data source, so activity appears in both places

Viewing All Kudos

Admins can see all kudos activity in Gamification > Analytics. The kudos table shows the giver, receiver, message, date, and points awarded for each transaction.

Tips

  • Add the Kudos Feed block to your community homepage or sidebar to make recognition visible
  • Consider adding kudos sending directly to member profile pages where it is easy to reach
  • The giver earning points (even just 2) encourages members to actively give recognition rather than passively receive it
  • Pair kudos with a "Most Recognized" challenge (based on kudos received) to make recognition a community event

Notifications

WB Gamification tells members what they have earned in real time. Notifications appear as toast popups on the frontend, as BuddyPress inbox notifications, and as activity feed entries.

Toast Notifications

Toast notifications are small popups that appear in the bottom-right corner of the page immediately after a member earns a reward. They disappear automatically after 4 seconds.

There are six notification types:

Type When It Shows Example
Points After any point-earning action "+10 points - Activity update posted"
Badge When a badge is earned "Badge earned: Community Pillar"
Level up When advancing to a new level "You reached Contributor!"
Streak milestone When hitting a streak milestone "30-day streak! Keep it up."
Challenge completed When a challenge is finished "Challenge complete: Weekend Writer"
Kudos received When someone sends kudos "[Member] sent you kudos"

Each toast is dismissible. Members can click it to close it early, or just wait for it to disappear.

Note: Silent awards (challenge bonus points, streak bonus points) do not show a points toast - only the challenge or streak notification fires.

BuddyPress Notifications

When BuddyPress is active, every significant gamification event creates a BuddyPress notification. Members see these in their notification bell in the header, just like friend requests and group invites. The following events create BuddyPress notifications:

  • Badge earned
  • Level-up
  • Challenge completed
  • Kudos received
  • Streak milestone hit

Members can mark these as read from the BuddyPress notifications panel the same way as any other notification.

Activity Feed Events

When BuddyPress is active, major achievements are also posted to the BuddyPress activity stream. This makes achievements visible to the whole community, not just the member who earned them. Activity feed events are created for:

  • Badge earned
  • Level-up
  • Kudos given (shows giver, receiver, and message)
  • Challenge completed

Activity feed posts from gamification events look and behave exactly like other BuddyPress activity. Members can like and comment on them.

Member Notification Preferences

Members can control how they receive notifications from their profile settings. The available preference is the notification mode:

Mode Behavior
smart (default) Notifications appear for meaningful events (badges, levels, milestones). Routine point toasts are shown but at reduced frequency to avoid noise.
all Every point award, badge, level-up, and other event shows a notification.
quiet Only major events (badge earned, level-up) trigger notifications. Routine point toasts are suppressed.

Members access their preference from their profile settings page. Admins can set the default mode in Gamification > Settings.

Admin-Side Notifications

Admins do not receive individual member-event notifications. Instead, the Analytics dashboard gives an overview of community-wide activity. The dashboard refreshes every 10 minutes and shows trends in points, badges, and active members.

Blocks and Shortcodes

WB Gamification includes 17 Gutenberg blocks (15 with matching shortcodes; daily-bonus and submit-achievement are block-only). Every shortcode renders identically to its block counterpart - use whichever fits your page-building workflow.

All shortcodes begin with [wb_gam_ and all blocks are found in the block inserter under the WB Gamification category.


Leaderboard

Displays a ranked list of members sorted by points for the chosen time period.

Block: WB Gamification Leaderboard Shortcode:

[wb_gam_leaderboard period="all" limit="10" show_avatars="1"]
[wb_gam_leaderboard period="week" limit="5" scope_type="group" scope_id="12"]
Attribute Default Options / Notes
period all all, month, week, day
limit 10 1-100
scope_type (empty) group to scope to a BuddyPress group
scope_id 0 BuddyPress group ID when scope_type="group"
show_avatars 1 0 to hide member avatars

Shows each member's avatar, name, rank number, and points. Highlights the current logged-in member's rank below the list even if they are not in the visible top entries.


Member Points

Shows the current (or specified) member's total points, level name, and progress toward the next level.

Block: WB Gamification Member Points Shortcode:

[wb_gam_member_points]
[wb_gam_member_points user_id="42" show_level="1" show_progress_bar="1"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
show_level 1 Show the level name
show_progress_bar 1 Show the progress bar toward next level

Badge Showcase

Displays a grid of badges the member has earned. Optionally shows locked (unearned) badges grayed out.

Block: WB Gamification Badge Showcase Shortcode:

[wb_gam_badge_showcase]
[wb_gam_badge_showcase show_locked="1" category="buddypress" limit="12"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
show_locked 0 1 to show unearned badges grayed out
category (empty) Filter by badge category (e.g. wordpress, buddypress, general)
limit 0 0 = show all; set a number to cap the display

Level Progress

Focused view of the member's current level, level icon, progress bar, and the points needed to reach the next level.

Block: WB Gamification Level Progress Shortcode:

[wb_gam_level_progress]
[wb_gam_level_progress show_next_level="1" show_icon="1"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
show_progress_bar 1 Show progress toward next level
show_next_level 1 Show the name and threshold of the next level
show_icon 1 Show the current level icon

Challenges

Displays active challenges with progress bars and time remaining.

Block: WB Gamification Challenges Shortcode:

[wb_gam_challenges]
[wb_gam_challenges limit="3" show_completed="0"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
limit 0 0 = show all active challenges
show_completed 1 0 to hide challenges the member has already finished
show_progress_bar 1 Show progress bar on each challenge

Streak

Displays the member's current streak count and optional activity heatmap.

Block: WB Gamification Streak Shortcode:

[wb_gam_streak]
[wb_gam_streak show_longest="1" show_heatmap="1" heatmap_days="90"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
show_longest 0 Also show the member's all-time longest streak
show_heatmap 0 Show a GitHub-style activity heatmap
heatmap_days 90 Days of history to show in the heatmap (1-365)

Top Members

Compact podium or list display of the top-ranking members. Ideal for sidebars and homepage sections.

Block: WB Gamification Top Members Shortcode:

[wb_gam_top_members]
[wb_gam_top_members limit="5" layout="list" show_badges="1" show_level="1"]
Attribute Default Options / Notes
limit 3 1-20
period all_time all_time, month, week, day
layout podium podium (visual 1st/2nd/3rd display) or list
show_badges 0 Show the member's top earned badge
show_level 0 Show the member's current level name

Kudos Feed

Displays a stream of recent kudos activity showing who gave kudos, who received it, and the message.

Block: WB Gamification Kudos Feed Shortcode:

[wb_gam_kudos_feed]
[wb_gam_kudos_feed limit="5" show_messages="0"]
Attribute Default Notes
limit 10 1-50
show_messages 1 0 to hide the kudos message text

Year Recap

Displays a member's year-in-review summary: total points, badges earned, top actions, and kudos sent and received. Best used on a dedicated "My Year" page.

Block: WB Gamification Year Recap Shortcode:

[wb_gam_year_recap]
[wb_gam_year_recap year="2024" show_share="1" show_badges="1" show_kudos="1"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
year 0 0 = current year
show_share 1 Show a share button
show_badges 1 Include badges section
show_kudos 1 Include kudos section
accent_color (empty) Hex color for accent elements (e.g. #6366f1)

Points History

Displays a paginated table of the member's point transaction history with action label, points earned, and date.

Block: WB Gamification Points History Shortcode:

[wb_gam_points_history]
[wb_gam_points_history limit="20" show_action_label="1"]
Attribute Default Notes
user_id 0 0 = currently logged-in member
limit 20 1-100 rows to display
show_action_label 1 Show the human-readable action name

Earning Guide

Displays a formatted grid of all active point-earning actions and their values. Use this on a help or onboarding page to explain how members can earn points.

Block: WB Gamification Earning Guide Shortcode:

[wb_gam_earning_guide]
[wb_gam_earning_guide columns="3" show_category_headers="true"]
Attribute Default Notes
columns 3 Number of columns in the grid (1-4)
show_category_headers true Show section headers per integration (WordPress, BuddyPress, etc.)

Using Shortcodes in Classic Widgets and Theme Files

All shortcodes work anywhere WordPress processes shortcodes - pages, posts, text widgets, and theme template files using do_shortcode(). They do not require the block editor to be active.

Analytics

The Analytics dashboard gives you a high-level view of how your community's gamification program is performing. All data is aggregated and read-only - you cannot modify any records from this screen.

Accessing the Dashboard

Go to Gamification > Analytics in your WordPress admin.

Period Selector

At the top of the dashboard, a period selector lets you choose between three reporting windows:

Period What It Shows
7 days Activity from the past week
30 days Activity from the past month (default)
90 days Activity from the past quarter

Changing the period reloads all KPI cards and tables for that window.

KPI Cards

Six summary cards appear at the top of the page:

Points Awarded - Total points given to all members during the selected period. A rising trend indicates increasing member participation.

Active Members - Number of distinct members who earned at least one point during the period. Compare this against your total member count to see your engagement rate.

Badges Earned - Total badge awards during the period. A drop in this number can indicate members have collected the easy badges and you may need new milestone badges.

Badge Earn Rate - Percentage of active members who also earned a badge during the period. Useful for understanding whether your badge thresholds are achievable.

Challenge Completion Rate - Percentage of members who started a challenge and completed it. Low completion rates may indicate challenge targets are too high or time windows too short.

Streak Health - Percentage of members with a current streak greater than 0. This measures day-over-day retention - members maintaining a streak are likely to return tomorrow.

Top Actions Table

Below the KPI cards, a table shows the top point-earning actions ranked by total points awarded during the period. Columns:

  • Action name
  • Number of times the action was performed
  • Total points awarded from this action
  • Number of distinct members who performed it

Use this table to understand which behaviors your members are taking most often. If a high-value action (like completing a course) rarely appears, consider whether it is promoted enough or whether the points value is motivating.

Top Earners Table

A table of the top point-earners for the period with their avatar, name, total points in the period, and rank.

This is distinct from the public leaderboard - it shows only the selected period and is only visible to admins.

Daily Points Sparkline

A small line chart shows total points awarded each day across the selected period. Use it to spot days with unusually high or low activity, and correlate with events like challenge launches or content publishing.

Data Freshness

All analytics queries are cached for 10 minutes. The dashboard notes the last-refreshed time at the bottom of the page. If you need up-to-the-minute data after a major manual award, wait 10 minutes or clear the object cache.

What Is Not Shown

The analytics dashboard shows aggregate data only. It does not show:

  • Individual member point transactions (see Gamification > Members for that)
  • Historical data beyond 90 days via the period selector (though all data remains in the database)
  • Real-time live updates - the page must be reloaded to see fresh data

Privacy

WB Gamification is built with GDPR compliance in mind. Member data is exportable, erasable, and partially controllable by the member themselves through preference settings.

What Data Is Collected

WB Gamification stores the following data associated with each member's user ID:

  • Point events - a log of every action that earned points, including the action type, points awarded, timestamp, and optional metadata (such as word count)
  • Badge records - which badges were earned and when, plus expiry dates where applicable
  • Level state - the member's current level, derived from their point total
  • Streak data - current streak count, longest streak, last active date, and timezone
  • Challenge progress - progress toward each challenge and completion timestamps
  • Kudos sent and received - giver, receiver, message, and timestamp for every kudos transaction
  • Member preferences - leaderboard opt-out status, show_rank setting, and notification mode

No payment data, private messages beyond kudos messages, or off-site tracking is stored.

WordPress Privacy Tools Integration

WB Gamification integrates with WordPress's built-in privacy tools found at Tools > Privacy. You can use these tools to handle data subject requests.

Personal Data Export

When an admin initiates a personal data export for a member (from Tools > Export Personal Data), WB Gamification adds the following to the export file:

  • Full point history with action labels, points, and dates
  • All earned badges with names and earned dates
  • Current level name and total points
  • All kudos sent, including recipient names and messages
  • All kudos received, including sender names and messages
  • Current streak count and longest streak
  • Challenge completion records
  • Notification and privacy preference settings

The export is provided as a ZIP file containing an HTML report the member can read directly.

Personal Data Erasure

When an admin initiates a personal data erasure for a member (from Tools > Erase Personal Data), WB Gamification deletes:

  • All point event records for that user
  • All earned badge records for that user
  • All kudos records where the user is either giver or receiver
  • The streak record for that user
  • All challenge progress records for that user
  • The member preference record for that user

After erasure, the member's gamification history is permanently gone. This action is irreversible.

Note: Erasing a member's data does not affect leaderboard snapshots that were already generated before the erasure. Those snapshots are anonymized automatically when cached data expires.

Member Preferences

Members can control two privacy-related settings from their profile:

Leaderboard opt-out - When enabled, the member is excluded from all leaderboard snapshots. They will not appear on any public leaderboard, including the Leaderboard block and Top Members block. This setting takes effect on the next leaderboard cache refresh (within 10 minutes).

Show rank - When disabled, the member's rank is hidden on their public profile. They can still see their own rank privately, but other members visiting their profile will not see it.

Notification mode - Controls the frequency and types of notifications the member receives. See the Notifications documentation for details.

Members find these settings in their profile settings page under the Gamification section. If BuddyPress is active, this is within the BuddyPress profile settings. Without BuddyPress, it appears in the standard WordPress user profile screen.

Admin Data Controls

Admins can:

  • View any member's full point history via Gamification > Members
  • Award or adjust points manually with a logged reason
  • Award or revoke badges manually
  • View all kudos activity in the Analytics dashboard
  • Prune old event logs via WP-CLI (wp wb-gamification logs prune --before=6months) to manage database size without affecting member-facing data

Data Retention

By default, point event logs are kept indefinitely. On large sites, this can add up to significant database storage over time. Use the WP-CLI log prune command to delete raw event logs older than a specified date. Point totals, badge records, and level state are not affected by pruning - only the detailed event log entries are removed.

Settings

Admin configuration for all gamification features

Points & Actions

Go to WB Gamification > Points in your admin sidebar.

The Actions Table

Each row represents one user behavior that can earn points. Actions are detected automatically from active plugins - no setup required. You will not see any rows until at least one supported plugin (WordPress core, BuddyPress, WooCommerce, etc.) is active.

The table has five columns:

Column What it controls
On Checkbox. Uncheck to disable the action entirely. Disabled actions earn zero points and fire no badges or challenges.
Action The name and description of the behavior, e.g. "Publish a post" or "Upload media."
Points How many points a member earns each time this action fires. Enter any whole number from 0 to 9999.
Repeat Whether the action can be earned more than once. Yes means every occurrence earns points. Once means the member earns points only the first time. This is set per-action in the manifest and cannot be changed from the admin.
Daily cap The maximum number of times this action counts in a single day. Shows a number or ∞ (unlimited). Like Repeat, this is defined in the manifest and is read-only in the table.

Changing point values

  1. Find the action row.
  2. Edit the number in the Points column.
  3. Click Save Changes at the bottom of the page.

Changes take effect immediately for any future action. Past points are not recalculated.

Enabling and disabling actions

Uncheck the On toggle next to any action and save. Members performing that action will no longer earn points, badges, or challenge progress from it.

Action categories

Actions are grouped into cards by category:

Category Source
WordPress Core WordPress events - publishing posts, comments, user registration
BuddyPress Social events - profile updates, activity posts, friendships, group joins
Commerce WooCommerce - purchases, product reviews
Learning LearnDash - course completions, quiz scores
Social Reactions, kudos, and other peer-recognition events
General Actions from other integrations or custom manifests

If a category does not appear, the plugin that provides it is not active on your site.

Understanding "Repeatable" and "Daily Cap"

Repeatable: Once - Useful for one-time milestones like "Complete your profile" or "Write your first post." The member earns the points exactly one time, no matter how many times they perform the action.

Repeatable: Yes - The action counts every time. Use the Daily Cap to prevent abuse.

Daily cap - A hard ceiling on how many times an action can earn points in one calendar day (UTC). For example, if commenting has a daily cap of 10, a member who posts 50 comments earns points for only the first 10 each day.

Log Retention

Below the action categories, the Log Retention card controls how long the points history table keeps rows.

Field Default Range
Keep points history for 6 months 1-24 months

Rows older than this value are pruned automatically by WP-Cron once per day. The events table (the source of truth) is never pruned. This means you can always recalculate totals from events even after the points log is trimmed.

Reduce this value on high-traffic sites to keep the database lean. Increase it if you rely on per-period analytics.

Click Save Changes to apply.

Levels Configuration

Go to WB Gamification > Levels in your admin sidebar.

Levels give members a visible rank as they accumulate points. A member's level updates automatically the moment their cumulative points cross a threshold - no cron job or manual refresh needed.

The Levels Table

The table lists every level ordered from lowest to highest threshold.

Column Description
Level Name The display name members see on their profile, e.g. "Newcomer," "Member," "Veteran."
Min Points Required The cumulative point total a member needs to reach this level.
Delete Removes the level. The starting level (0 points) cannot be deleted.

Editing existing levels

  1. Click into the Level Name or Min Points Required field for any row.
  2. Change the value.
  3. Click Save Levels.

All members are re-evaluated against the new thresholds on their next activity. If you lower a threshold, members already past that point keep their current (higher) level - they are not downgraded.

The 0-point starting level has its Min Points field locked at 0 and displays "Starting level." You can rename it but not delete or change its threshold.

Adding a New Level

The Add New Level card below the table adds a new threshold.

Field Description
Level Name Required. A short name for the new level.
Min Points Required Required. Must be at least 1.

Fill both fields and click Add Level. The new row appears in the table sorted by points threshold.

Recommended structure

  • Always keep one level at 0 points. This is the default rank for all new members.
  • Space thresholds far enough apart that members must genuinely engage to advance.
  • Give levels meaningful names that reflect community status.

Example:

Level Name Min Points
Newcomer 0
Member 100
Regular 500
Veteran 2,000
Legend 10,000

Deleting a Level

Click Delete next to any non-zero level. You will see a confirmation prompt. Deleting a level does not remove any member's points. Members who were at the deleted level fall back to the highest remaining level below their point total.

The starting level (Min Points = 0) is protected and cannot be deleted. Always keep at least one level at 0 so new members have a default rank immediately.

Badge Management

Go to WB Gamification > Badges in your admin menu.

Badges are visual rewards that recognize specific milestones, achievements, or behaviors. Members earn them automatically or receive them from an admin. The badge library shows all badges in a grid. Each card shows the badge icon, name, how many members have earned it, and whether it awards automatically or requires manual granting.

Creating a New Badge

Click + Create New Badge in the toolbar. A form appears with two sections: badge details and award condition.

Badge Details

Field Required Description
Badge ID Yes A unique machine-readable identifier. Lowercase letters, numbers, and underscores only (e.g. first_post). Cannot be changed after creation.
Name Yes The display name shown to members when they earn the badge (e.g. "First Post").
Description No Explains what the badge is for. Shown on badge cards and the public share page.
Icon No An image from your Media Library. Recommended size: 128×128 px PNG with a transparent background. Click Choose Icon to open the media picker. Click Remove to clear it.
Category No Groups badges in the frontend showcase. Options: General, Points, WordPress, BuddyPress, Special.
Is Credential No Marks the badge as a verifiable OpenBadges 3.0 credential. Members can share a verified badge URL - useful for professional achievements on LinkedIn.
Closes at No A date and time after which no new members can earn this badge. Leave blank for no cutoff. Displayed in your site's timezone.
Max earners No The maximum number of members who can earn this badge. Once reached, the badge stops auto-awarding. Leave blank for unlimited.

Auto-Award Condition

This section controls how the badge is awarded.

Condition When it awards
Admin awarded only (manual) The badge is never awarded automatically. Only admins can grant it via the Award Points page or the Badges page.
Reaches a point milestone Awards automatically when a member's total points reach or exceed a threshold you specify. Enter the point value in Points Threshold.
Performs an action N times Awards automatically when a member completes a specific action a set number of times. Choose the Action from the dropdown and enter the Target Count.

Click Create Badge to save.

Editing a Badge

Click any badge card in the grid to open its edit form. All fields are editable except the Badge ID. Change what you need and click Save Changes.

Deleting a Badge

While editing a badge, click Delete Badge. Confirm the prompt. This permanently removes the badge definition and all earned records. Members who previously held the badge will lose it from their profiles.

The 30 Default Badges

The plugin ships with 30 pre-built badge definitions covering common milestones (first post, point milestones, social actions, tenure). They appear in the badge grid on a fresh install. You can edit, delete, or supplement them with your own.

Challenge Manager

Go to WB Gamification > Challenges in your admin menu.

Challenges give members a time-limited goal: perform a specific action a set number of times before the deadline to earn bonus points. Progress counts only while the challenge is active.

Creating a Challenge

The Create Challenge form is at the top of the page.

Field Required Default Description
Title Yes - A short name shown to members on the challenge card, e.g. "Post 10 photos this week."
Action Yes - The user behavior that counts toward this challenge. Choose from all registered actions (same list as the Points tab).
Target Count Yes 10 How many times the member must perform the action to complete the challenge. Minimum 1.
Bonus Points No 50 Extra points awarded when the member hits the target. Set to 0 for a challenge with no point bonus (e.g. badge-only reward).
Start Date No Now When the challenge becomes available. Actions before this date do not count.
End Date No 7 days from now The deadline. Members must reach the target before this date and time.

Click Create Challenge to save. The new challenge appears in the All Challenges list below.

The Challenge List

The table shows all challenges with these columns:

Column Description
Title Challenge name
Action The action being tracked
Target Required action count
Bonus Bonus points on completion
Status Active or other status
Dates Start date → End date
Actions Edit or Delete buttons

Editing a Challenge

Click Edit next to any challenge. The form at the top of the page fills with the existing values. Make your changes and click Update Challenge. Click Cancel to go back without saving.

Deleting a Challenge

Click Delete in the challenge row. Confirm the prompt. This removes the challenge definition. Member progress toward the deleted challenge is not removed from the events log, but the challenge no longer appears to members.

Notes on Challenge Design

  • Default 7-day duration. The end date defaults to 7 days from when you create the challenge. Adjust this for shorter sprints (24-hour flash challenges) or longer campaigns.
  • Actions must be enabled. If you disable an action on the Points tab, it will not count toward challenges that use it.
  • One action per challenge. Each challenge tracks a single action type. To create multi-action goals, create multiple challenges and use a badge as the reward for completing all of them.
  • Bonus points stack with regular points. Members earn their normal per-action points throughout the challenge period, plus the bonus on completion.

Kudos Settings

Go to WB Gamification > Kudos in your admin sidebar.

Kudos is a peer-recognition system. Members send kudos to each other to say "great work." Both the giver and the receiver can earn points, which encourages participation on both sides.

Fields

Max kudos per day

Default: 5

The maximum number of kudos a single member can send in one calendar day. Once a member hits this limit, they cannot send more until the next day.

This prevents kudos flooding. If members are using kudos to farm points for a friend, lower this value. If you want kudos to feel free and frictionless, raise it.

Recommended values by community size:

Community size Suggested limit
Small (< 100 members) 3-5
Medium (100-1,000) 5-10
Large (1,000+) 10-20

Points per kudos received

Default: 5

The number of points the recipient earns each time they receive a kudos. This rewards members for creating content and behavior that others appreciate.

Set to 0 if you want kudos to be symbolic recognition without point value.

Points per kudos given

Default: 2

The number of points the sender earns each time they give kudos to another member. Keeping this lower than the receiver value ensures that the primary reward goes to the person being recognized, not the person clicking the button.

Set to 0 if you only want the receiver to benefit.

Saving

Click Save Changes after adjusting any value. Changes apply to all future kudos immediately. Existing kudos in the log are not retroactively recalculated.

Notes

  • Kudos daily limits and point values work independently. You can have a high limit with low point values (social and lightweight) or a low limit with high point values (rare and meaningful).
  • The Kudos feed block ([wb_gam_kudos_feed] shortcode) displays recent kudos activity on the frontend.
  • If BuddyPress is active, kudos events also appear in the BuddyPress activity stream.

Rank Automation Rules

Go to WB Gamification > Rules in your admin sidebar.

Rank Automation rules trigger actions automatically when a member reaches a specific level. Use them to onboard members into groups, grant role upgrades, or send congratulatory messages - all without writing any code.

How rules work

Each rule has:

  • A trigger - which level the member must reach
  • An action - what happens when they reach it

Rules fire once per member per level. If a member already passed a level before you created a rule for it, they will not receive the action retroactively.

You can add multiple rules for the same level. Each rule triggers independently.

Adding a New Rule

Fill in the Add New Rule form at the bottom of the page.

Step 1: Choose the trigger level

Select the level from the When member reaches level dropdown. This list shows all levels you have configured in the Levels tab.

Step 2: Choose the action type

Select one of the three action types from the Perform action dropdown. The form shows only the fields relevant to your selection.


Action type: Add to BuddyPress group

Automatically adds the member as a member of a BuddyPress group.

Field Description
BuddyPress Group ID The numeric ID of the group. Find this in BuddyPress > Groups - hover over a group name and look for gid= in the URL.

Use case: Add members who reach "Veteran" level to a private "VIP Members" group, giving them access to exclusive content.


Action type: Add WordPress role

Adds a WordPress role to the member's account. This adds the role - it does not replace their existing roles.

Field Description
Role slug The lowercase WordPress role slug, e.g. contributor, editor, or a custom role slug registered by another plugin.

Use case: Grant contributor access to members who reach the "Regular" level, allowing them to submit posts for review.


Action type: Send BuddyPress message

Sends a private BuddyPress message to the member from a specified user.

Field Description
Message sender user ID The user ID of the account that appears as the sender. Defaults to 1 (the site admin).
Message subject The subject line of the private message.
Message content The body of the message. Plain text.

Use case: Send a congratulations message when a member reaches "Gold" level, including instructions for their new benefits.


Click Add Rule to save. The rule appears in the rules table immediately.

Viewing and deleting rules

The rules table shows:

Column Description
When member reaches The level name that triggers the rule
Action The action type
Parameters The configuration values (group ID, role, or message details)

Click Delete next to any rule and confirm the prompt to remove it. Deleting a rule does not undo actions already performed for members who previously reached the level.

Use case examples

Goal Trigger level Action type Configuration
Welcome new members to a starter group Newcomer (0 pts) Add to BP group Group ID of your "All Members" group
Unlock content for engaged members Regular (500 pts) Add WP role subscriber-plus (custom role)
Personally congratulate top contributors Legend (10,000 pts) Send BP message Sender = admin, personalized message
Give editors posting rights at Veteran level Veteran (2,000 pts) Add WP role contributor

Manual Point Awards

Go to WB Gamification > Award Points in your admin menu.

Use this page to grant or deduct points from any member directly. All awards go through the standard points engine, so badges, level-ups, streaks, and hooks fire exactly as they would for any automatic event.

The Award Form

User

A dropdown listing all WordPress users. Select the member who will receive or lose points.

Points

Enter a positive number to award points. Enter a negative number to deduct points.

The maximum you can award or deduct in a single action is ±10,000 points.

Examples:

  • 100 - awards 100 points
  • -50 - deducts 50 points
  • 10000 - awards the maximum in one action

Reason / Note

Optional. A short note stored with the award entry and shown in the recent history table below. Maximum 200 characters.

The note is visible only to admins. It is not shown to the member.

Use this to document why you made the adjustment. Examples from the form placeholder: "Contest winner," "Support bonus," "Policy violation."

Click Award Points to submit.

Recent Manual Awards

The table below the form shows the 20 most recent manual awards. Each row shows:

Column Description
User The member's display name
Points The amount awarded (green badge) or deducted (red badge)
Note The reason entered at the time
Date The date and time of the award in your site's date/time format

The note shown is the most recent note stored for each user, not necessarily the note from that specific row. Notes are stored as user meta, so if you award a user twice, the note column for older rows will show the most recent note.

Common use cases

Rewarding contest winners Run a community photo contest. Award the top three entries 500, 300, and 100 points respectively. Enter "Photo contest - 1st place" in the reason field.

Support bonuses A member helped another user solve a complex problem. Award 50 bonus points with the note "Community support bonus."

Policy violations A member spammed the activity feed. Deduct 100 points with the note "Spam warning - policy violation." Combine this with a WP role change via Rank Automation if needed.

Onboarding boosts Give new members a 25-point welcome bonus to help them reach the first level threshold faster.

Notes

  • You cannot award more than ±10,000 points per form submission. For larger adjustments, submit the form multiple times.
  • Deducting points below zero is possible. A member's total can go negative if you deduct more than they have earned.
  • All manual awards appear in the points log alongside automatic events.

API Keys

Go to WB Gamification > API Keys in your admin menu.

API keys let remote sites connect to this WordPress installation as a centralized gamification hub. A remote site sends requests to this site's REST API using the key as an authentication credential.

Generating a New Key

Fill in the Generate New Key form.

Field Required Description
Label Yes A human-readable name for the key. Use the name of the site or application it belongs to, e.g. "MediaVerse Production."
Site ID No A short machine-readable identifier for the remote site, e.g. mediaverse-prod. Used for per-site reporting and filtering in the points log.

Click Generate Key.

Copy the key immediately

The full API key is shown once in a notice at the top of the page immediately after generation. It will not be shown again. Copy it now and store it securely (a password manager or secrets vault).

After you navigate away from the page, the key table shows only the first 12 characters followed by ... - enough to identify the key but not enough to use it.

The Active Keys Table

Column Description
Label The name you gave the key
Site ID The machine identifier you provided
Key (prefix) First 12 characters of the key for identification
Created When the key was generated
Last Used The most recent time the key authenticated a request, or - if unused
Status Active or Revoked
Actions Revoke and Delete buttons

Revoking a key

Click Revoke next to an active key. The key remains in the table with a "Revoked" status badge. Requests sent with a revoked key are rejected with a 401 response. The remote site is immediately locked out without deleting the audit record.

Use revoke when you suspect a key has been compromised but want to keep the entry visible for review.

Deleting a key

Click Delete next to any key (active or revoked) and confirm the prompt. The key is permanently removed from the database. Unlike revoking, this removes the record entirely.

Use delete to clean up keys from decommissioned sites.

How authentication works

Remote sites include the key in the X-WB-Gam-Key HTTP request header:

X-WB-Gam-Key: your-api-key-here

Any request to the WB Gamification REST API (/wp-json/wb-gamification/v1/) that includes a valid active key is authenticated as an admin-level consumer. All endpoints are available to authenticated key requests.

Typical use case: centralized gamification

You operate multiple WordPress sites in your network. One site acts as the gamification hub - it holds all the point rules, badge definitions, and leaderboards. Each other site has WB Gamification installed in remote mode and sends events to the hub via REST API using its own API key. Members accumulate points across all connected sites in one unified profile.

Generate one key per remote site. Label each key clearly so you can identify and revoke individual sites if needed.

Pro Features

Advanced features available with the Pro add-on

WB Gamification Pro - Overview

WB Gamification Pro is an add-on for the free WB Gamification plugin. It requires the free plugin to be installed and active. You also need a valid EDD license key, which you activate under WB Gamification → License.

What Pro Adds

The free plugin covers points, badges, levels, leaderboard, individual challenges, streaks, kudos, and all integration manifests. Pro adds nine optional engines on top of that foundation.

Feature Flag What It Does
cohort_leagues Duolingo-style weekly competitions with promotion/demotion
weekly_emails Automated weekly recap emails to members
leaderboard_nudge Motivational emails when a member is close to climbing
status_retention Prevents level drops for engaged members
cosmetics Profile frames and cosmetic items members can equip
community_challenges Team/global challenges with shared progress
site_first_badges Badges for the first member to complete a specific action
tenure_badges Automatic anniversary and milestone badges
badge_share Public share pages with OG tags, LinkedIn, OpenBadges 3.0

Pro also includes two additional engines with no feature flag - the Redemption Store (spend points on rewards) and Outbound Webhooks (Zapier/Make/n8n). Both activate as soon as the pro add-on is active.

How Feature Flags Work

All nine flags default to off after installation. You enable each one individually under WB Gamification → Settings → Pro Features. This lets you roll out features incrementally without activating everything at once.

The free plugin's FeatureFlags class checks for the constant WB_GAM_PRO_VERSION at boot. If the pro add-on is not active, no pro engines load - even if flags are saved as enabled in the database.

Requirements

  • WB Gamification (free) 1.0.0 or higher - active
  • WordPress 6.0 or higher
  • PHP 8.1 or higher
  • Valid EDD license key

Activation Steps

  1. Install and activate the free WB Gamification plugin first.
  2. Upload and activate wb-gamification-pro.
  3. Go to WB Gamification → License.
  4. Enter your license key and click Activate License.
  5. Go to WB Gamification → Settings → Pro Features.
  6. Toggle on the features you want to use.

Cohort Leagues

Cohort Leagues add Duolingo-style weekly competitions to your community. Instead of every member competing against everyone else, members compete in small groups of similar ability. This makes competition feel winnable for average members - not just your top performers.

How It Works

At the start of each week, the CohortEngine automatically sorts members into cohorts based on their tier. Members in the same tier compete only against each other for that week.

At the end of the week, the engine evaluates each cohort:

  • Top performers in a cohort get promoted to a higher tier the following week.
  • Bottom performers get demoted to a lower tier.
  • Middle performers stay in place.

Point totals reset each week. Historical points (used for levels and badges) are unaffected - cohort leagues track weekly points separately.

Tiers

The default tier structure runs from bottom to top. New members start in the lowest tier. Exact tier names and thresholds are configurable in the league settings.

Why It Drives Engagement

Weekly resets create recurring motivation. Members who missed last week's top spot have a fresh chance every Monday. The promotion/demotion mechanic gives both top and bottom performers a reason to act - one to protect a hard-earned tier, the other to escape demotion.

The cohort model also prevents discouragement. A member with 200 points never appears on the same leaderboard as a member with 20,000 points.

Setup

  1. Go to WB Gamification → Settings → Pro Features.
  2. Enable the Cohort Leagues toggle.
  3. Go to WB Gamification → Leagues to configure tier names, cohort size, and promotion/demotion thresholds.
  4. The engine runs its weekly sort automatically via WordPress cron.

Requirements

  • Pro add-on active
  • cohort_leagues feature flag enabled

Community Challenges

Community Challenges let your entire membership work toward a shared goal - similar to Pokémon GO's community events. Every member's qualifying actions contribute to a single global progress bar. When the community hits the target, everyone earns bonus points.

How It Differs from Individual Challenges

Individual challenges (free feature) are per-member: each person has their own progress bar and wins or loses independently. Community challenges have one progress bar shared across all participants. No member can complete it alone.

Creating a Community Challenge

  1. Go to WB Gamification → Community Challenges → Add New.
  2. Set a title and description visible to members.
  3. Choose the action that contributes to progress (any registered gamification action, e.g., bp_activity_update).
  4. Set the target count - total number of qualifying actions needed.
  5. Set a deadline (date and time).
  6. Set the bonus points awarded to every member on completion.
  7. Click Publish.

The CommunityChallengeEngine hooks into the event bus. Each time the chosen action fires, it increments the global counter by one.

What Members See

Members see the challenge title, description, current global progress, target, and time remaining. You can display this with the [wb_gam_community_challenge] shortcode or the Challenges Gutenberg block.

On Completion

When the global counter reaches the target before the deadline, every member who made at least one contributing action receives the bonus points. The challenge status changes to Completed.

If the deadline passes before the target is reached, the challenge expires without awarding bonus points.

Requirements

  • Pro add-on active
  • community_challenges feature flag enabled

Redemption Store

The Redemption Store lets members spend their accumulated points on rewards you define. It closes the loop on your points economy - points become worth something tangible, which increases the motivation to earn them.

Creating a Reward Item

  1. Go to WB Gamification → Redemption Store → Add Reward.
  2. Enter a title and description visible to members.
  3. Set the points cost required to redeem.
  4. Choose a reward type:
Reward Type What It Does
discount_pct Generates a percentage-off coupon code
discount_fixed Generates a fixed-amount coupon code
custom You define the fulfillment manually
  1. Optionally set a stock limit. When stock hits zero, the item becomes unavailable.
  2. Click Publish.

How Members Redeem

Members browse available rewards on the store page (use the [wb_gam_store] shortcode or the REST endpoint GET /wp-json/wb-gamification/v1/redemption/items). When they redeem an item, the RedemptionController deducts the points cost and creates a transaction record.

For discount reward types, a WooCommerce coupon code is generated automatically and shown to the member. For custom rewards, you handle fulfillment manually and mark the redemption as fulfilled in the admin.

Transaction Log

Every redemption is recorded with the member ID, reward ID, points spent, timestamp, and fulfillment status. View the log at WB Gamification → Redemption Store → Transactions.

Stock Management

Stock counts decrement on each successful redemption. If you set no stock limit, the reward is unlimited. You can update stock at any time from the reward edit screen.

Requirements

  • Pro add-on active (no separate feature flag required)

Badge Sharing

Badge Sharing gives each earned badge a public URL with proper Open Graph meta tags and optional LinkedIn credential support. Members can share proof of their achievements on social networks or add them to their LinkedIn profile as verified certifications.

Share URL Format

Every earned badge gets a public page at:

/wb-gamification/badge/{user-login}/{badge-slug}/

The BadgeSharePage engine generates this page dynamically. It outputs:

  • Open Graph title, description, and image (the badge artwork)
  • Twitter Card meta tags
  • A canonical URL

OpenBadges 3.0 Credentials

When a badge is marked as a credential (is_credential: true in the badge definition), the share page also outputs a verifiable JSON-LD credential following the OpenBadges 3.0 specification. This makes the badge machine-readable and verifiable by third-party tools.

The credential JSON is available at:

GET /wp-json/wb-gamification/v1/credential/{user_id}/{badge_id}

LinkedIn "Add to Profile" Link

Credential badges include a pre-built LinkedIn deep-link on the share page. Clicking it takes the member directly to LinkedIn's "Add Certification" flow with the badge name, issuer, and credential URL pre-filled. No copying and pasting required.

How to Enable Credential Badges

  1. Go to WB Gamification → Badges.
  2. Edit the badge you want to make shareable as a credential.
  3. Check the Is Credential option.
  4. Save the badge.

Non-credential badges still get OG share pages - they just do not output the JSON-LD block or the LinkedIn link.

Feature Flag

Enable badge sharing under WB Gamification → Settings → Pro Features → Badge Share.

Requirements

  • Pro add-on active
  • badge_share feature flag enabled

Outbound Webhooks

Outbound Webhooks let WB Gamification send real-time event data to external services like Zapier, Make (formerly Integromat), or n8n. Each time a qualifying event fires on your site, the WebhookDispatcher sends a signed HTTP POST to your configured endpoint.

Supported Events

Event When It Fires
points_awarded Any time a member earns points
badge_earned A badge is awarded to a member
level_changed A member moves to a new level
streak_milestone A member hits a streak milestone
challenge_completed An individual challenge is completed
kudos_given A member gives kudos to another member

Creating a Webhook

  1. Go to WB Gamification → Webhooks → Add Webhook.
  2. Enter the destination URL (your Zapier webhook URL, Make webhook, etc.).
  3. Check the events you want this endpoint to receive.
  4. Click Save. The plugin generates a secret key for this webhook.

You can create multiple webhooks for different destinations or event subsets.

Payload Format

Each POST request sends a JSON body:

{
  "event": "points_awarded",
  "user_id": 42,
  "data": { ... },
  "timestamp": 1700000000
}

The exact data keys vary by event type.

Verifying Signatures

Every request includes an X-WB-Gam-Signature header. The value is an HMAC-SHA256 hash of the raw request body, signed with the webhook's secret key.

To verify in your receiving application:

$signature = hash_hmac( 'sha256', $raw_body, $secret_key );
// Compare with the X-WB-Gam-Signature header value.

Always verify signatures before processing webhook data. Reject any request where the signature does not match.

Admin Management

View all registered webhooks, their last delivery status, and recent delivery logs at WB Gamification → Webhooks. You can pause, edit, or delete any webhook from this screen.

Requirements

  • Pro add-on active (no separate feature flag required)

Weekly Recap Emails

Weekly Recap Emails automatically send every member a personalized summary of their gamification activity from the past seven days. The WeeklyEmailEngine handles scheduling, content assembly, and delivery via WordPress's built-in mail system.

What the Email Contains

Each email shows the member:

  • Points earned during the week
  • Badges unlocked during the week
  • Current streak status
  • Leaderboard position (if leaderboard is active)

The email uses your site name and custom sender details.

Configuration

  1. Enable the feature under WB Gamification → Settings → Pro Features → Weekly Emails.
  2. Go to WB Gamification → Settings → Emails.
  3. Set the sender name and sender email address.
  4. Optionally customize the email subject line.

Emails send automatically once per week via WordPress cron (wp_wb_gam_weekly_email). The send day and time are configurable in settings.

Disabling for Individual Members

Members can opt out of recap emails from their profile notification preferences. The engine respects the wb_gam_member_prefs table - members with email notifications disabled are skipped.

Troubleshooting Delivery

If emails are not sending, check:

  1. WordPress cron is running (wp cron event list).
  2. Your hosting environment allows wp_mail() outbound connections.
  3. The feature flag is enabled.

For reliable delivery on high-volume sites, use a transactional email service (SendGrid, Mailgun, Postmark) connected via a WordPress SMTP plugin.

Requirements

  • Pro add-on active
  • weekly_emails feature flag enabled

Cosmetics and Profile Frames

Cosmetics let members personalize their community presence using visual items - profile frames, overlays, or custom CSS effects. The CosmeticEngine manages the item catalog, member inventory, and equipped state.

Creating a Cosmetic Item

  1. Go to WB Gamification → Cosmetics → Add Item.
  2. Enter a name for the item (visible to members).
  3. Choose the type (e.g., profile_frame, overlay).
  4. Upload the asset (image URL or CSS asset) in the Asset URL field.
  5. Optionally enter a CSS class to apply when the item is equipped.
  6. Set the award type:
Award Type How Members Get It
admin_grant You assign it manually to specific members
purchase Members spend points from their balance
  1. If purchase, enter the points cost.
  2. Click Save.

How Members Equip Cosmetics

Members browse their cosmetic inventory on their profile page and click to equip an item. Only one item of each type can be equipped at a time. Equipping a new frame automatically unequips the previous one.

BuddyPress Profile Display

When BuddyPress is active, equipped cosmetics appear on the member's BP profile avatar and profile header. The CosmeticEngine outputs the asset and CSS class via the BuddyPress profile display hooks.

Awarding Cosmetics to Members

To grant a cosmetic item to a specific member:

  1. Go to WB Gamification → Cosmetics → Items.
  2. Click the item name.
  3. Under Grant to Members, search for and select the member.
  4. Click Grant.

You can also award cosmetics automatically as badge rewards or level-up bonuses using the Rules engine.

Requirements

  • Pro add-on active
  • cosmetics feature flag enabled

Integrations

Auto-detected plugin integrations and their actions

Integrations Overview

WB Gamification connects to other WordPress plugins automatically. You do not configure integrations manually - the ManifestLoader scans for manifest files at plugins_loaded priority 5 and registers their actions before the engine boots.

How Auto-Discovery Works

Each integration is a PHP file that returns an array of trigger definitions. When the target plugin is active, the manifest loads and its actions become available in the points engine, badge rules, and challenge conditions. If the target plugin is not active, the manifest returns an empty array and is skipped entirely.

First-party manifests ship inside the integrations/ directory of WB Gamification itself. Drop-in manifests ship inside the target plugin (like WPMediaVerse Pro) and are discovered automatically when that plugin is installed.

Supported Integrations

Plugin Actions Manifest Location
WordPress Core 8 integrations/wordpress.php
BuddyPress 10 integrations/buddypress.php
bbPress 3 integrations/bbpress.php
WooCommerce 4 integrations/woocommerce.php
LearnDash 5 integrations/learndash.php
LifterLMS 5 integrations/contrib/lifterlms.php
MemberPress 3 integrations/contrib/memberpress.php
GiveWP 4 integrations/contrib/givewp.php
The Events Calendar 3 integrations/contrib/the-events-calendar.php
WPMediaVerse Pro 17 wpmediaverse-pro/wb-gamification.php

Total: 62 gamification actions across 10 integrations.

Zero Configuration

Once an integrated plugin is active, its actions appear immediately in:

  • The points engine (with default point values you can override)
  • Badge award conditions
  • Challenge target conditions
  • The Actions admin screen (WB Gamification → Actions)

Default point values are set per action in each manifest. You can override any default from WB Gamification → Actions → Edit.

Checking Integration Status

Run wp wb-gamification doctor --verbose to see which integrations are detected, how many actions are registered per integration, and whether any duplicate hook registrations exist.

BuddyPress Integration

The BuddyPress integration is the most comprehensive integration in WB Gamification. It covers the core social loop - posting, commenting, friending, and group activity - as well as BuddyPress add-ons for reactions, polls, member blogs, and media.

The manifest loads automatically when BuddyPress is active. No configuration is required.

Actions

Action ID Label Default Points Repeatable
bp_activity_update Post an activity update 10 Yes (30s cooldown)
bp_activity_comment Comment on an activity 5 Yes (30s cooldown)
bp_friends_accepted Accept a friendship 8 Yes
bp_groups_join Join a group 8 Yes
bp_groups_create Create a group 20 Yes
bp_profile_complete Complete extended profile 15 No (once only)
bp_reactions_received Receive a reaction 3 Yes
bp_polls_created Create a poll 10 Yes
bp_publish_post Publish a member blog post 25 Yes
bp_media_upload Upload media 5 Yes (60s cooldown)

Notes

  • bp_friends_accepted awards the member who accepts the request, not the one who initiated it.
  • bp_profile_complete fires on xprofile_updated_profile. It is non-repeatable - a member earns it once.
  • bp_reactions_received requires the BuddyPress Reactions add-on.
  • bp_polls_created requires the BuddyPress Polls add-on.
  • bp_publish_post requires the BP Member Blog add-on and awards on publish_post for post post type only. Pages and custom post types are excluded.
  • bp_media_upload requires the BuddyPress Media add-on.

Profile Display

When BuddyPress is active, WB Gamification adds a gamification panel to member profiles showing points, level, badges, and streak. This is handled by ProfileIntegration and DirectoryIntegration.

Activity Feed

Points and badge events post to the BuddyPress activity feed via BPActivity. Members see their own achievements and (optionally) achievements from members they follow.

Member Directory

The member directory gains a sort option for Most Points when BuddyPress Directory Integration is active.

WooCommerce Integration

The WooCommerce integration rewards purchasing behavior and product engagement. The manifest loads automatically when WooCommerce is active.

Actions

Action ID Label Default Points Repeatable
wc_order_completed Complete a purchase 25 Yes
wc_first_purchase Complete first purchase ever 50 No (once only)
wc_product_reviewed Leave a product review 15 Yes (1/product/day)
wc_wishlist_add Add a product to wishlist 5 Yes (5min cooldown)

Notes

  • wc_first_purchase fires on the same hook as wc_order_completed but checks whether this is the customer's first completed order. It only awards points when exactly one completed order exists for that customer.
  • wc_product_reviewed fires on comment_post with a guard that checks the post type is product and the comment is approved. This prevents double-awarding if you also have the WordPress Core comment action active.
  • wc_wishlist_add requires the YITH WooCommerce Wishlist plugin. It fires on yith_wcwl_added_to_wishlist.

Preventing Double Points on Reviews

The WooCommerce manifest's review action explicitly checks post_type === 'product'. The WordPress Core manifest's comment action targets non-product post types. The two actions do not overlap.

Requirements

  • WooCommerce active

LearnDash Integration

The LearnDash integration rewards learners at every stage of the course progression path - from individual topics through to full course completion and instructor-approved assignments.

The manifest loads automatically when LearnDash is active.

Actions

Action ID Label Default Points Repeatable
ld_course_completed Complete a LearnDash course 100 Yes
ld_lesson_completed Complete a LearnDash lesson 15 Yes
ld_topic_completed Complete a LearnDash topic 5 Yes
ld_quiz_passed Pass a LearnDash quiz 25 Yes
ld_assignment_approved Assignment approved by instructor 20 Yes

Notes

  • ld_topic_completed uses the manifest default of 5 points (the source file shows 5, not 15 - see the topic entry).
  • ld_quiz_passed only awards points when the learner actually passes (the pass flag in the quiz data is true). Failed quiz attempts earn nothing.
  • ld_assignment_approved fires when an instructor marks an assignment as approved, not when the learner submits it. This rewards quality work, not just submission.
  • All five actions are repeatable with no cooldown, so learners earn points every time they complete a lesson or course - even if they revisit it.

Recommended Point Structure

The default values reward depth of engagement. A learner who completes an entire course earns 100 points for the course itself plus 15 per lesson and 5 per topic along the way. Adjust point values to reflect how much depth matters in your learning community.

Requirements

  • LearnDash active

bbPress Integration

The bbPress integration rewards forum participation. The manifest loads automatically when bbPress is active.

Actions

Action ID Label Default Points Repeatable
bbp_new_topic Create a forum topic 10 Yes (5min cooldown)
bbp_new_reply Post a forum reply 5 Yes (60s cooldown)
bbp_topic_closed Topic resolved / closed 20 Yes

Notes

  • bbp_topic_closed fires when a topic is marked as closed or resolved. It awards points to the topic author, not the moderator who closed it. The action checks $r['is_closed'] - reopening a topic does not trigger the award.
  • Cooldowns on bbp_new_topic (5 minutes) and bbp_new_reply (60 seconds) prevent abuse from rapid posting.

Relationship to BuddyPress Integration

bbPress and BuddyPress actions are separate and do not conflict. A forum reply is a different action from a BuddyPress activity update - they fire on different hooks and represent different types of community participation. You can have both integrations active at the same time.

Requirements

  • bbPress active

Other Plugin Integrations

WB Gamification includes drop-in manifests for four additional plugins. Each manifest lives in integrations/contrib/ and loads automatically when its target plugin is active.


LifterLMS

Action ID Label Default Points
llms_course_completed Complete a LifterLMS course 100
llms_lesson_completed Complete a LifterLMS lesson 10
llms_quiz_passed Pass a LifterLMS quiz 25
llms_achievement_earned Earn a LifterLMS achievement 30
llms_certificate_earned Earn a LifterLMS certificate 50

llms_quiz_passed only awards points when the attempt returns passed: true. llms_certificate_earned rewards the final milestone in any course that issues certificates.

Requires: LifterLMS active (LLMS_Student class present)


MemberPress

Action ID Label Default Points Repeatable
mp_membership_activated Activate a membership 50 Yes (1hr cooldown)
mp_membership_renewed Renew a membership 30 Yes
mp_first_membership Join as paid member (first time) 100 No (once only)

mp_first_membership fires on the same hook as mp_membership_activated but checks whether the member has only one subscription. It awards once per lifetime.

Requires: MemberPress active (MeprUser class present)


GiveWP

Action ID Label Default Points Repeatable
give_donation_completed Complete a donation 30 Yes
give_first_donation Make first donation ever 75 No (once only)
give_recurring_donation Make a recurring donation payment 20 Yes
give_campaign_goal_reached Campaign reaches its goal 15 Yes

GiveWP's design recognizes the act of donating, not the amount. Point values are not tied to donation size - this preserves donor privacy and avoids rewarding larger donors disproportionately. give_recurring_donation requires the GiveWP Recurring Donations add-on.

Requires: GiveWP active (give() function present)


The Events Calendar

Action ID Label Default Points
tec_rsvp_registered RSVP to an event 10
tec_ticket_purchased Purchase an event ticket 20
tec_event_checked_in Check in to an event 15

tec_rsvp_registered only awards on "going" RSVPs - declining an RSVP earns nothing. tec_event_checked_in reads the _tribe_tickets_attendee_user_id post meta to identify the member.

Requires: The Events Calendar active (Tribe__Events__Main class present)

WPMediaVerse Pro Integration

WPMediaVerse Pro ships its own gamification manifest (wb-gamification.php in the plugin root). When both WPMediaVerse Pro and WB Gamification are active, ManifestLoader discovers the file automatically and registers all 17 actions. No configuration is needed.

This is a drop-in manifest - it lives inside WPMediaVerse Pro, not inside WB Gamification. That means manifest updates ship with WPMediaVerse Pro releases.

Actions by Category

Media (content creation and engagement received)

Action ID Label Default Points
mvs_upload_photo Upload a photo 10
mvs_create_album Create an album 15
mvs_receive_like Receive a like on photo 2
mvs_receive_comment Receive a comment on photo 5
mvs_receive_favorite Photo bookmarked by someone 2

mvs_receive_like and mvs_receive_favorite award the media owner, not the person who reacted. Self-likes (liking your own content) are excluded - the engine compares the reactor ID against the media author and returns 0 if they match.

Social (engagement given - awards the actor)

Action ID Label Default Points Daily Cap
mvs_receive_follow Gain a new follower 3 -
mvs_give_comment Write a meaningful comment 3 20
mvs_give_follow Follow another member 1 50
mvs_bookmark_photo Bookmark a photo 1 30

mvs_give_comment requires the comment to be 20 or more characters. Single-word or empty comments earn nothing. Daily caps prevent point farming.

Note: mvs_receive_follow awards the member being followed (social category), not the follower - it appears here because it measures social growth.

Competition

Action ID Label Default Points
mvs_battle_win Win a photo battle 100
mvs_challenge_participate Enter a photo challenge 10
mvs_challenge_win_1st Win 1st place in a challenge 200
mvs_challenge_win_2nd Win 2nd place in a challenge 100
mvs_challenge_win_3rd Win 3rd place in a challenge 50
mvs_tournament_round_win Win a tournament round 150
mvs_tournament_win Win a tournament 500

Competition actions have no cooldowns or daily caps - they are high-stakes events that fire infrequently by design.

Engagement (streaks)

Action ID Label Default Points
mvs_streak_milestone Hit an upload streak milestone 50 (base)

mvs_streak_milestone fires when a member hits 7, 30, 100, or 365 consecutive upload days. The manifest uses a points_callback that reads the $xp bonus passed by WPMediaVerse Pro's streak engine - the actual points awarded may exceed the 50-point default depending on streak length.

Requirements

  • WPMediaVerse Pro active
  • WB Gamification (free) active

BuddyPress

BuddyPress-specific display and social features

BuddyPress Profile Display

Overview

WB Gamification automatically adds a rank badge to every member's BuddyPress profile header. No shortcode or configuration is required. As soon as both plugins are active, every profile shows the member's current level name, total point count, and a progress bar toward the next level.

What Members See

The rank block appears inside the bp_before_member_header_meta hook, directly below the member's avatar and name.

Element Source
Level name wb_gam_level_name user meta, defaults to "Newcomer"
Point count Summed from wb_gam_points ledger
Progress bar (current_points - current_level_min) / (next_level_min - current_level_min) × 100

The progress bar is only rendered when a next level exists in the wb_gam_levels table.

Default Level Names

Fresh installs seed five levels:

Level Minimum Points
Newcomer 0
Member 100
Contributor 500
Regular 1,500
Champion 5,000

You can rename or add levels at WP Admin → Gamification → Levels.

HTML Structure

<div class="wb-gam-profile-rank">
  <span class="wb-gam-rank-badge">Contributor</span>
  <span class="wb-gam-points-count">650 pts</span>
  <div class="wb-gam-progress-bar" title="30%">
    <div class="wb-gam-progress-fill" style="--wb-gam-fill:30%"></div>
  </div>
</div>

The fill width is driven by a CSS custom property --wb-gam-fill. Override it in your theme to change the bar colour or animation.

Styling with CSS Variables

/* Override in your child theme or Custom CSS */
.wb-gam-profile-rank {
  --wb-gam-bar-color: #6366f1;
  --wb-gam-bar-bg: #e5e7eb;
  --wb-gam-bar-height: 6px;
}

Opt-Out: Hiding the Rank

Members can hide their rank badge. The preference is stored in wb_gam_member_prefs.show_rank (default 1 = visible).

When show_rank = 0, the render_rank() method returns early and nothing is output. The NULL state (no row in the table) also defaults to visible.

Setting the preference via SQL (admin use only)

-- Hide rank for user 42
INSERT INTO wp_wb_gam_member_prefs (user_id, show_rank)
VALUES (42, 0)
ON DUPLICATE KEY UPDATE show_rank = 0;

Setting the preference via REST API

POST /wp-json/wb-gamification/v1/members/42/prefs
Authorization: Bearer <cookie nonce>
Content-Type: application/json

{ "show_rank": false }

No Configuration Needed

ProfileIntegration::init() is called on the bp_loaded action. It performs a function_exists('buddypress') guard before registering any hooks. If BuddyPress is deactivated, the block silently does nothing.

BuddyPress Activity Feed Integration

Overview

WB Gamification posts four types of events to the BuddyPress activity stream automatically. These entries create social proof - other members see achievements as they happen and are naturally encouraged to participate.

All four event types are registered under the wb_gamification component and appear in the "Gamification" filter group in the activity stream.

Event Types

Event Activity Type Hook That Triggers It
Badge earned badge_earned wb_gam_badge_awarded
Level reached level_changed wb_gam_level_changed
Kudos given kudos_given wb_gam_kudos_given
Challenge completed challenge_completed wb_gam_challenge_completed

Each activity entry links back to the member's BuddyPress profile URL via bp_core_get_user_domain().

Example Activity Text

  • Badge earned: "Jane Smith earned the Community Voice badge"
  • Level reached: "Jane Smith reached the Contributor level"
  • Kudos given: "Jane Smith gave kudos to Tom Harris: Great answer!"
  • Challenge completed: "Jane Smith completed the 7-Day Streak challenge"

Toggling Individual Event Types

Each stream event type is individually toggled via a WordPress option. The default for all four is enabled (1).

Option Key Default Controls
wb_gam_bp_stream_badge_earned 1 Badge earned posts
wb_gam_bp_stream_level_changed 1 Level-up posts
wb_gam_bp_stream_kudos_given 1 Kudos given posts
wb_gam_bp_stream_challenge_completed 1 Challenge completed posts

Disable a specific event type

// Disable kudos posts in the activity stream.
update_option( 'wb_gam_bp_stream_kudos_given', 0 );

Re-enable via admin (Settings → Gamification → BuddyPress)

You can also toggle these from the admin settings page without writing code.

Quality-Weighted Reactions

ActivityIntegration also hooks into the wb_gam_points_for_action filter to apply a quality bonus. When a member receives a reaction on an activity_update post (rather than a comment or other type), the points awarded for bp_reactions_received are boosted to a minimum of 5 (compared to the default 3).

// This filter runs at priority 10 inside ActivityIntegration.
add_filter( 'wb_gam_points_for_action', function( $points, $action_id, $user_id, $event ) {
    // Only modifies bp_reactions_received on activity_update posts.
    if ( 'bp_reactions_received' === $action_id && 'activity_update' === ( $event->metadata['activity_type'] ?? '' ) ) {
        return max( $points, 5 );
    }
    return $points;
}, 10, 4 );

You can override this behaviour by adding your own filter at a higher priority.

How Posts Appear in the Stream

All posts use bp_activity_add() with hide_sitewide: false, so they appear on the site-wide activity feed as well as the member's profile feed. Posts are never marked as spam.

The item_id field varies per event:

  • badge_earned - always 0
  • level_changed - the new level's DB row ID
  • kudos_given - the wb_gam_kudos row ID (for linking)
  • challenge_completed - the challenge's DB row ID

No Configuration Required

ActivityIntegration::init() runs on bp_loaded and performs a function_exists('buddypress') guard. If BuddyPress is not active, no hooks are registered.

BuddyPress Member Directory Integration

Overview

WB Gamification adds a compact rank badge next to each member's name in the BuddyPress member directory. The badge shows the member's current level name only - no point count or progress bar, keeping the directory listing clean.

What Appears in the Directory

A single <span> with the level name is injected via the bp_directory_members_item action hook:

<span class="wb-gam-directory-rank">Contributor</span>

This appears inside each member list item, adjacent to the member's name and avatar.

Who Sees a Rank Badge

The badge only appears under two conditions:

  1. The member has earned a level (i.e., wb_gam_level_name user meta is set and non-empty).
  2. The member has not opted out of showing their rank (wb_gam_member_prefs.show_rank is not 0).

Members who have never earned any points - and therefore have no level assigned - show no badge at all. "Newcomer" (the default starting level) will appear once the user meta is written, which happens on the first level-up evaluation.

Opt-Out Behaviour

The directory badge respects the same show_rank preference as the profile header. If a member sets show_rank = 0 in wb_gam_member_prefs, their badge is hidden from both the profile header and the directory listing.

A NULL value (no row in the preferences table) defaults to visible.

Styling the Directory Badge

/* Target the rank badge in the member directory */
.wb-gam-directory-rank {
  display: inline-block;
  padding: 2px 8px;
  font-size: 0.75rem;
  background: var(--wb-gam-rank-bg, #f3f4f6);
  color: var(--wb-gam-rank-color, #374151);
  border-radius: 9999px;
  margin-left: 6px;
  vertical-align: middle;
}

Add this to your child theme's stylesheet or via Appearance → Customize → Additional CSS.

No Configuration Required

DirectoryIntegration::init() is called on bp_loaded. It guards with function_exists('buddypress') before registering any hooks. Deactivating BuddyPress removes the integration silently.

Developer Guide

Technical reference for developers integrating with WB Gamification

Getting Started for Developers

WB Gamification is built as a platform -- not just a plugin. Choose your path based on what you're building.

Three Paths

Path 1: WordPress Plugin Developer

"I want to add gamification to my plugin"

The fastest way is a manifest file -- a single PHP file that tells WB Gamification what actions your plugin provides.

  1. Create wb-gamification.php in your plugin's root directory
  2. Return an array of action definitions
  3. WB Gamification auto-discovers it on activation

See the full manifest tutorial Download the manifest template

For advanced use cases, use the PHP API directly:

// Register a custom action programmatically.
wb_gam_register_action( array(
    'id'             => 'my_plugin_action',
    'label'          => 'Custom Action',
    'hook'           => 'my_plugin_did_something',
    'user_callback'  => fn() => get_current_user_id(),
    'default_points' => 25,
    'category'       => 'my-plugin',
) );

// Check if a user has earned a badge.
if ( wb_gam_has_badge( $user_id, 'first-post' ) ) {
    // Show special content.
}

// Award points manually.
wb_gam_award_points( $user_id, 50, 'custom_reward' );

See all PHP API functions

Path 2: Theme Developer

"I want to display gamification data in my theme"

Use Gutenberg blocks or shortcodes -- no PHP knowledge needed.

Blocks (recommended): Add any of the 17 blocks in the editor: Leaderboard, Hub, Member Points, Points History, Badge Showcase, Earning Guide, Daily Bonus, Streak, Challenges, Community Challenges, Cohort Rank, Top Members, Kudos Feed, Submit Achievement, Level Progress, Redemption Store, Year Recap.

Shortcodes (classic themes):

[wb_gam_hub]
[wb_gam_leaderboard period="week" limit="10"]
[wb_gam_member_points]
[wb_gam_badge_showcase show_locked="1"]
[wb_gam_level_progress]
[wb_gam_challenges]
[wb_gam_streak]
[wb_gam_earning_guide]

PHP template tags:

// In your theme templates:
$points = wb_gam_get_user_points( get_current_user_id() );
$level  = wb_gam_get_user_level( get_current_user_id() );
$badges = wb_gam_get_user_badges( get_current_user_id() );
$streak = wb_gam_get_user_streak( get_current_user_id() );

See all blocks and shortcodes

Path 3: App / Headless Developer

"I want to build a mobile app or headless frontend"

Use the REST API with API key authentication.

Setup:

  1. Generate an API key in WP Admin > Gamification > API Keys
  2. Use the key in the X-WB-Gam-Key header

JavaScript SDK (recommended):

import { WBGamification } from '@wbcom/wb-gamification';

const client = new WBGamification({
  baseUrl: 'https://your-site.com',
  apiKey: 'your-api-key',
});

const leaders = await client.getLeaderboard('week', 10);
const member  = await client.getMember(42);
await client.submitEvent(42, 'completed_lesson', { lesson_id: 5 });

Direct REST API:

# Get leaderboard
curl -H "X-WB-Gam-Key: YOUR_KEY" \
  https://your-site.com/wp-json/wb-gamification/v1/leaderboard?period=week

# Award points
curl -X POST -H "X-WB-Gam-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id":42,"action_id":"manual","points":50}' \
  https://your-site.com/wp-json/wb-gamification/v1/events

OpenAPI spec: GET /wp-json/wb-gamification/v1/openapi.json -- import into Postman, Swagger UI, or any OpenAPI tool.

Webhooks for real-time event notifications to your backend: See webhook documentation

See full REST API reference


Architecture Overview

Trigger Sources
  |- WordPress hooks (publish_post, wp_login, etc.)
  |- BuddyPress hooks (bp_activity_posted, etc.)
  |- REST API (POST /events)
  |- WP-CLI (wp wb-gamification points award)
  |- Manifest files (auto-discovered)
       |
Event Normalization -> WB_Gam_Event
       |
Rule Evaluation Engine
  |- PointsEngine  -> append-only points ledger
  |- BadgeEngine   -> rule-based badge awards
  |- LevelEngine   -> threshold-based progression
  |- ChallengeEngine -> time-bound goals
  |- StreakEngine   -> daily/weekly tracking
  |- KudosEngine   -> peer recognition
       |
Output Consumers
  |- Gutenberg blocks (17 blocks)
  |- BuddyPress (profile, directory, activity)
  |- REST API (18 controllers)
  |- Webhooks (Zapier, Make, n8n)
  |- Toast notifications
  |- Your custom code (hooks + PHP API)

Extension Points

Layer How to extend Documentation
Add actions Manifest file or wb_gam_register_action() Manifest tutorial
Modify points wb_gam_points_for_action filter Hooks reference
Custom badge rules wb_gam_should_award_badge filter Hooks reference
React to events wb_gam_after_points_award action Hooks reference
React to badges wb_gam_after_badge_award action Hooks reference
React to levels wb_gam_level_changed action Hooks reference
Custom display Shortcodes, blocks, or PHP API Blocks & shortcodes
External systems Webhooks or REST API Webhooks, REST API

Architecture

Design Principle

WB Gamification is event-sourced. The only write path is:

Event in → Rules evaluate → Effects out

All gamification state (points, badges, levels, streaks) is derived from the immutable wb_gam_events table. BuddyPress display, WooCommerce triggers, and the REST API are consumers of this pipeline - they never write state directly.

Boot Sequence

All hooks register on plugins_loaded. The priority order ensures each layer is ready before the next depends on it.

Priority Component What It Does
0 WB_Gamification::instance() Registers all hooks, constants, autoloader
1 DbUpgrader::init() Runs schema migrations if wb_gam_db_version is behind
5 ManifestLoader::scan() Auto-discovers wb-gamification.php manifests in every plugin directory
6 Registry::init() Registers discovered actions and badge triggers; fires wb_gam_register
8 Engine::init(), WPHooks, BPHooks Boots the event pipeline; registers WordPress and BuddyPress trigger hooks
10 BadgeEngine, ChallengeEngine, StreakEngine, etc. Secondary engines subscribe to wb_gam_points_awarded
12 NotificationBridge Subscribes to badge/level/streak hooks to dispatch BP notifications
15 Privacy Registers GDPR erasure and export handlers
20 SiteFirstBadgeEngine Subscribes last so site-first-action checks see all other state
bp_loaded ProfileIntegration, DirectoryIntegration, ActivityIntegration BuddyPress surface integrations, after BP is fully booted

PSR-4 Namespace Map

Namespace Directory Purpose
WBGam\Engine\ src/Engine/ Core engines, event bus, DB, cron
WBGam\API\ src/API/ REST controllers (16 controllers)
WBGam\Admin\ src/Admin/ Admin pages, setup wizard, analytics
WBGam\BuddyPress\ src/BuddyPress/ BP profile, directory, activity integrations
WBGam\Integrations\ src/Integrations/ WordPress, WooCommerce, and other plugin hooks
WBGam\Abilities\ src/Abilities/ WordPress Abilities API capability registrations
WBGam\Blocks\ src/Blocks/ Gutenberg block render callbacks
WBGam\Extensions\ src/Extensions/ Public helper functions (functions.php)
WBGam\CLI\ src/CLI/ WP-CLI command classes

Engine Pipeline

Every gamification event flows through Engine::process() in this order:

1. Validate (user_id > 0, action_id not empty)
2. Check action enabled  (get_option wb_gam_enabled_{action_id})
3. Rate-limit gate       (daily_cap, cooldown - PointsEngine::passes_rate_limits())
4. Enrich metadata       (apply_filters: wb_gam_event_metadata)
5. Before-evaluate gate  (apply_filters: wb_gam_before_evaluate - return false to abort)
6. Persist event         (INSERT wb_gam_events - UUID PK, immutable)
7. Calculate points      (admin option → wb_gam_points_for_action filter → RuleEngine multipliers)
8. Write points ledger   (INSERT wb_gam_points with event_id FK)
9. Fire hooks            (do_action: wb_gam_points_awarded)
10. Side effects         (LevelEngine::maybe_level_up, StreakEngine::record_activity, WebhookDispatcher::dispatch)

Steps 1-5 are synchronous and write nothing. Steps 6-10 are the only database writes. This means apply_filters('wb_gam_before_evaluate', true, $event) can abort processing without leaving any trace in the database.

Async Processing

High-volume actions can use Engine::process_async() instead of Engine::process(). This performs the rate-limit check synchronously (fast, no writes) then queues the full pipeline via Action Scheduler under the wb-gamification group.

If Action Scheduler is unavailable (unit tests, early boot), process_async() falls back to synchronous processing automatically.

Manifest Auto-Discovery

At priority 5, ManifestLoader::scan() runs two passes:

  1. First-party: loads every *.php file in wb-gamification/integrations/
  2. Third-party: scans WP_PLUGIN_DIR/*/wb-gamification.php - any installed plugin can declare triggers by dropping this file

Manifest files return a plain PHP array. They are read-only configuration - no dependency on WB Gamification being loaded when the file is included. If the gamification plugin is not installed, the file is simply ignored.

Constants

WB_GAM_VERSION   // '1.0.0'
WB_GAM_FILE      // absolute path to wb-gamification.php
WB_GAM_PATH      // plugin dir path (trailing slash)
WB_GAM_URL       // plugin dir URL (trailing slash)
WB_GAM_BASENAME  // 'wb-gamification/wb-gamification.php'

Database Version Tracking

The current schema version is stored in get_option('wb_gam_db_version'). On each boot at priority 1, DbUpgrader::init() compares this to WB_GAM_VERSION. If behind, it runs the appropriate upgrade_to_X_Y_Z() methods in sequence. Each version gets its own upgrade method - no compound migrations.

Hooks & Filters Reference

Complete reference for all action hooks and filter hooks in WB Gamification. Use these to extend the engine, add custom logic, or integrate with third-party systems.

Convention: Hooks prefixed wb_gamification_ are stable public API. Hooks prefixed wb_gam_ are internal (may change between versions).

Pro label: Hooks marked [Pro] fire only when the Pro add-on is active. They are safe to hook into from any code - they simply never fire without Pro.


Action Hooks

Points

wb_gam_before_points_awarded

Fires before points are written to the ledger. All checks have passed (enabled, rate limits, gate filter, multipliers). Last chance to inspect or log before it becomes permanent.

add_action( 'wb_gam_before_points_awarded', function( int $user_id, $event, int $points ) {
    // Log high-value awards to a custom table.
    if ( $points >= 100 ) {
        error_log( "High award: {$points} pts to user {$user_id} for {$event->action_id}" );
    }
}, 10, 3 );
Parameter Type Description
$user_id int User who will receive the points
$event Event Full event object (action_id, metadata, object_id)
$points int Final points after all multipliers

wb_gam_points_awarded

Fires after points are written to the ledger. The most-used hook - triggers badge evaluation, level check, streak update, and notifications.

add_action( 'wb_gam_points_awarded', function( int $user_id, $event, int $points ) {
    // Sync points to an external CRM.
    my_crm_update_points( $user_id, $points, $event->action_id );
}, 10, 3 );
Parameter Type Description
$user_id int User who earned the points
$event Event Full event object
$points int Points awarded

wb_gam_points_revoked

Fires when an admin revokes (deletes) a point award via the REST API.

add_action( 'wb_gam_points_revoked', function( int $row_id, array $row, int $admin_id ) {
    // Notify the user their points were revoked.
}, 10, 3 );

wb_gam_points_redeemed

Fires when a member redeems points for a reward in the redemption store.

add_action( 'wb_gam_points_redeemed', function( int $redemption_id, int $user_id, array $item, ?string $coupon ) {
    // Send a confirmation email with the coupon code.
}, 10, 4 );

Badges

wb_gam_badge_awarded

Fires after a badge is awarded to a member.

add_action( 'wb_gam_badge_awarded', function( int $user_id, array $badge_def, string $badge_id ) {
    // Post to Slack when someone earns a special badge.
    if ( 'founding_member' === $badge_id ) {
        slack_notify( "User {$user_id} earned Founding Member!" );
    }
}, 10, 3 );

wb_gam_credential_expired [Pro]

Fires when a badge credential passes its expires_at date during the daily expiry check.

add_action( 'wb_gam_credential_expired', function( int $user_id, string $badge_id, string $expires_at ) {
    // Notify the user to renew their credential.
}, 10, 3 );

Levels

wb_gam_level_changed

Fires when a member moves to a different level (up or down). Does NOT fire on initial assignment to "Newcomer".

add_action( 'wb_gam_level_changed', function( int $user_id, int $old_level_id, int $new_level_id ) {
    // Assign a WordPress role based on level.
    if ( $new_level_id >= 5 ) {
        $user = get_user_by( 'id', $user_id );
        $user->set_role( 'contributor' );
    }
}, 10, 3 );

Streaks

wb_gam_streak_milestone

Fires when a member reaches a streak milestone (7, 14, 30, 60, 100, 180, or 365 days).

add_action( 'wb_gam_streak_milestone', function( int $user_id, int $streak_days ) {
    if ( $streak_days >= 30 ) {
        \WBGam\Engine\BadgeEngine::award_badge( $user_id, 'dedicated_30' );
    }
}, 10, 2 );

wb_gam_streak_broken

Fires when a member's streak is reset to 1 after exceeding the grace period.

add_action( 'wb_gam_streak_broken', function( int $user_id, int $old_streak, int $gap_days ) {
    // Send a "We miss you" email if they had a long streak.
    if ( $old_streak >= 14 ) {
        wp_mail( get_userdata( $user_id )->user_email, 'Your streak ended', '...' );
    }
}, 10, 3 );
Parameter Type Description
$user_id int User whose streak broke
$old_streak int Streak count before reset
$gap_days int Days of inactivity that caused the break

Challenges

wb_gam_challenge_completed

Fires when a member completes a challenge (reaches the target count).

add_action( 'wb_gam_challenge_completed', function( int $user_id, array $challenge ) {
    my_analytics_track( 'challenge_completed', [
        'user_id'      => $user_id,
        'challenge_id' => $challenge['id'],
        'title'        => $challenge['title'],
    ] );
}, 10, 2 );

wb_gam_challenge_created

Fires when an admin creates a new challenge.

wb_gam_challenge_updated

Fires when an admin updates an existing challenge.

wb_gam_challenge_deleted

Fires when an admin deletes a challenge.

wb_gam_community_challenge_completed [Pro]

Fires when a community (team) challenge reaches its global target.


Kudos

wb_gam_kudos_given

Fires after kudos are successfully recorded.

add_action( 'wb_gam_kudos_given', function( int $giver_id, int $receiver_id, string $message, int $kudos_id ) {
    // Post to BuddyPress activity stream.
}, 10, 4 );

Pro Engine Hooks

wb_gam_weekly_email_sent [Pro]

Fires after a weekly recap email is sent.

wb_gam_weekly_nudge [Pro]

Fires when a leaderboard nudge email is sent.

wb_gam_cosmetic_granted [Pro]

Fires when a cosmetic/frame is granted to a member.

wb_gam_cohort_outcome [Pro]

Fires when a cohort league season ends with promotion/demotion results.

add_action( 'wb_gam_cohort_outcome', function( int $user_id, int $old_tier, int $new_tier, string $outcome, int $points ) {
    // $outcome is 'promoted', 'demoted', or 'stayed'.
}, 10, 5 );

wb_gam_retention_nudge [Pro]

Fires when a re-engagement nudge is sent to an inactive member.

wb_gam_personal_record

Fires when a member sets a personal record.


System Hooks

wb_gam_engines_booted

Fires after all engines have initialized. Pro plugin hooks here to register additional engines.

wb_gam_register

Fires after the Registry is initialized. Last chance to register actions via the manual API.

wb_gam_rank_automation_action

Fires when a rank automation rule is triggered.

wb_gam_log_pruned

Fires after the daily log pruner runs.

wb_gam_user_data_erased

Fires after all gamification data for a user is erased (GDPR).


Filter Hooks

wb_gam_points_for_action

Modify points before they are written. Called after admin option lookup, before multipliers.

// Double points on weekends.
add_filter( 'wb_gam_points_for_action', function( int $points, string $action_id, int $user_id, $event ) {
    if ( in_array( gmdate( 'l' ), [ 'Saturday', 'Sunday' ], true ) ) {
        return $points * 2;
    }
    return $points;
}, 10, 4 );

wb_gam_before_evaluate

Gate filter - return false to silently block an event from being processed.

// Block all gamification for suspended users.
add_filter( 'wb_gam_before_evaluate', function( bool $proceed, $event ) {
    if ( get_user_meta( $event->user_id, 'is_suspended', true ) ) {
        return false;
    }
    return $proceed;
}, 10, 2 );

wb_gam_event_metadata

Enrich event metadata before rule evaluation.

add_filter( 'wb_gam_event_metadata', function( array $metadata, $event ) {
    if ( isset( $metadata['content'] ) ) {
        $metadata['word_count'] = str_word_count( wp_strip_all_tags( $metadata['content'] ) );
    }
    return $metadata;
}, 10, 2 );

wb_gam_should_award_badge

Gate filter - return false to prevent a specific badge from being awarded.

// Only award "Top Contributor" to users with 6+ months membership.
add_filter( 'wb_gam_should_award_badge', function( bool $should, int $user_id, string $badge_id, array $def ) {
    if ( 'top_contributor' === $badge_id ) {
        $registered = strtotime( get_userdata( $user_id )->user_registered );
        if ( time() - $registered < 6 * MONTH_IN_SECONDS ) {
            return false;
        }
    }
    return $should;
}, 10, 4 );

wb_gam_streak_grace_days

Override the grace period (days before streak breaks) per user.

// Pro members get 3 grace days instead of 1.
add_filter( 'wb_gam_streak_grace_days', function( int $days, int $user_id ) {
    if ( user_can( $user_id, 'premium_member' ) ) {
        return 3;
    }
    return $days;
}, 10, 2 );

wb_gam_before_kudos

Validate or block kudos before they are recorded. Return a WP_Error to reject.

// Require minimum account age to give kudos.
add_filter( 'wb_gam_before_kudos', function( $result, int $giver_id, int $receiver_id, string $message ) {
    $registered = strtotime( get_userdata( $giver_id )->user_registered );
    if ( time() - $registered < WEEK_IN_SECONDS ) {
        return new WP_Error( 'too_new', 'Your account must be at least 7 days old to give kudos.' );
    }
    return $result;
}, 10, 4 );

wb_gam_leaderboard_results

Modify leaderboard data before it is returned to blocks, shortcodes, or the REST API.

// Add badge count to leaderboard entries.
add_filter( 'wb_gam_leaderboard_results', function( array $results, array $raw_rows ) {
    foreach ( $results as &$entry ) {
        $entry['badge_count'] = count( wb_gam_get_user_badges( $entry['user_id'] ) );
    }
    return $results;
}, 10, 2 );

wb_gam_toast_data

Modify toast notification content before it is queued. Return empty array to suppress.

// Suppress point toasts for minor actions.
add_filter( 'wb_gam_toast_data', function( array $event, int $user_id ) {
    if ( 'points' === ( $event['type'] ?? '' ) && ( $event['points'] ?? 0 ) < 5 ) {
        return []; // Suppress - too small to notify.
    }
    return $event;
}, 10, 2 );

wb_gam_credential_document

Modify the OpenBadges 3.0 JSON-LD credential before it is returned.

wb_gam_recap_data [Pro]

Modify the year-in-review recap data before display.

wb_gam_rank_automation_rules

Modify rank automation rules before they are evaluated.

wb_gam_should_send_weekly_nudge [Pro]

Control whether a weekly nudge email should be sent to a specific user.


Quick Reference Table

Actions (28 total)

Hook File Free/Pro
wb_gam_before_points_awarded Engine.php Free
wb_gam_points_awarded Engine.php Free
wb_gam_points_revoked PointsController.php Free
wb_gam_points_redeemed RedemptionEngine.php Free
wb_gam_badge_awarded BadgeEngine.php Free
wb_gam_credential_expired CredentialExpiryEngine.php Pro
wb_gam_level_changed LevelEngine.php Free
wb_gam_streak_milestone StreakEngine.php Free
wb_gam_streak_broken StreakEngine.php Free
wb_gam_challenge_completed ChallengeEngine.php Free
wb_gam_challenge_created ChallengeManagerPage.php Free
wb_gam_challenge_updated ChallengeManagerPage.php Free
wb_gam_challenge_deleted ChallengeManagerPage.php Free
wb_gam_community_challenge_completed CommunityChallengeEngine.php Pro
wb_gam_kudos_given KudosEngine.php Free
wb_gam_rank_automation_action RankAutomation.php Free
wb_gam_personal_record PersonalRecordEngine.php Free
wb_gam_weekly_email_sent WeeklyEmailEngine.php Pro
wb_gam_weekly_nudge LeaderboardNudge.php Pro
wb_gam_cosmetic_granted CosmeticEngine.php Pro
wb_gam_cohort_outcome CohortEngine.php Pro
wb_gam_retention_nudge StatusRetentionEngine.php Pro
wb_gam_log_pruned LogPruner.php Free
wb_gam_events_pruned LogPruner.php Free
wb_gam_user_data_erased Privacy.php Free
wb_gam_engines_booted FeatureFlags.php Free
wb_gam_register Registry.php Free

Filters (11 total)

Hook File Free/Pro
wb_gam_points_for_action Engine.php Free
wb_gam_before_evaluate Engine.php Free
wb_gam_event_metadata Engine.php Free
wb_gam_should_award_badge BadgeEngine.php Free
wb_gam_streak_grace_days StreakEngine.php Free
wb_gam_before_kudos KudosEngine.php Free
wb_gam_leaderboard_results LeaderboardEngine.php Free
wb_gam_toast_data NotificationBridge.php Free
wb_gam_credential_document CredentialController.php Free
wb_gam_recap_data RecapEngine.php Pro
wb_gam_rank_automation_rules RankAutomation.php Free
wb_gam_should_send_weekly_nudge LeaderboardNudge.php Pro

Block extension API

Every server-rendered block fires two action hooks (for HTML injection) and several expose a data filter (for data mutation before render).

Universal block actions (fire on all 15 blocks)

wb_gam_block_before_render

Fires immediately before a block emits any HTML. Use to inject UI above the block, log impressions, or short-circuit via output capture.

add_action( 'wb_gam_block_before_render', function( string $slug, array $attributes, array $context ) {
    if ( $slug === 'leaderboard' ) {
        echo '<div class="my-leaderboard-banner">Top players this week →</div>';
    }
}, 10, 3 );

wb_gam_block_after_render

Fires immediately after the block finishes its HTML. Use to append UI (share button, CTA), inject analytics beacons, or react to the render.

add_action( 'wb_gam_block_after_render', function( string $slug, array $attributes, array $context ) {
    if ( $slug === 'kudos-feed' && is_user_logged_in() ) {
        echo '<a class="my-give-kudos-cta" href="#">Send kudos →</a>';
    }
}, 10, 3 );

Per-block data filters

Filters fire on the data the block is about to render - devs can reorder, remove, or add fields. Each filter is named wb_gam_block_<slug>_data (or _currencies for the hub).

Filter Block Filtered value
wb_gam_block_leaderboard_data leaderboard Array of {rank, user_id, display_name, points} rows
wb_gam_block_top_members_data top-members Same shape as leaderboard
wb_gam_block_points_history_data points-history Array of {action_id, points, point_type, created_at} rows
wb_gam_block_member_points_data member-points {points, label, level, next_level, progress_pct} map
wb_gam_block_hub_currencies hub Array of {slug, label, icon, balance, is_default, convert_rules} tiles
wb_gam_block_badge_showcase_data badge-showcase Array of {id, name, icon_url, earned, ...} badges
wb_gam_block_challenges_data challenges Array of active challenges for the user
wb_gam_block_cohort_rank_data cohort-rank Array of cohort standings rows
wb_gam_block_community_challenges_data community-challenges Array of active community challenges
wb_gam_block_earning_guide_data earning-guide Category-keyed action map [ category => [{label,icon,points}, ...] ]
wb_gam_block_kudos_feed_data kudos-feed Array of recent kudos rows
wb_gam_block_level_progress_data level-progress {points, level, next, pct} map
wb_gam_block_redemption_store_data redemption-store Array of reward items
wb_gam_block_streak_data streak {streak, heatmap} map
wb_gam_block_year_recap_data year-recap Yearly recap aggregates map
// Example: hide certain users from every leaderboard.
add_filter( 'wb_gam_block_leaderboard_data', function( array $rows, array $attrs ) {
    return array_values( array_filter( $rows, fn( $r ) => ! in_array( $r['user_id'], [42, 99], true ) ) );
}, 10, 2 );

// Example: add a custom currency tile to the hub.
add_filter( 'wb_gam_block_hub_currencies', function( array $tiles, array $attrs, int $user_id ) {
    $tiles[] = [
        'slug'           => 'external_loyalty',
        'label'          => __( 'Loyalty', 'my-plugin' ),
        'icon'           => 'gem',
        'balance'        => my_external_loyalty_balance( $user_id ),
        'is_default'     => false,
        'convert_rules'  => [],
    ];
    return $tiles;
}, 10, 3 );

All 15 blocks expose a data filter - every member-facing render path is mutable from extension code without forking the render PHP.


Theme template overrides

Plugin-shipped templates can be overridden by themes via the standard locate_template() chain. Use Templates::locate() from any extension code:

$path = \WBGam\Engine\Templates::locate( 'emails/weekly-recap.php' );
// 1. Filter: wb_gam_template_path  (full programmatic override)
// 2. Theme:  {child-theme}/wb-gamification/emails/weekly-recap.php
// 3. Theme:  {parent-theme}/wb-gamification/emails/weekly-recap.php
// 4. Plugin: wb-gamification/templates/emails/weekly-recap.php

Email templates (always overridable)

Every email the plugin sends routes through Email::render()Templates::locate(), so the override path is identical to other plugin templates. Two emails ship today:

Template Slug Sent by Variables passed
templates/emails/weekly-recap.php weekly-recap WeeklyEmailEngine (Pro) user, name, site_name, points_this_week, total_points, badges_this_week, challenges_this_week, streak, rank, unsub_url
templates/emails/leaderboard-nudge.php leaderboard-nudge LeaderboardNudge user, name, site_name, site_url, message, rank, points

Override either by copying to your theme:

mkdir -p wp-content/themes/your-theme/wb-gamification/emails/
cp wp-content/plugins/wb-gamification/templates/emails/leaderboard-nudge.php \
   wp-content/themes/your-theme/wb-gamification/emails/

Then customise. Variables documented in the @var block at the top of each template are extracted into local scope.

Render directly:

echo \WBGam\Engine\Templates::render( 'emails/weekly-recap.php', [
    'user'   => $user,
    'points' => $points,
] );

Override a path entirely via filter:

add_filter( 'wb_gam_template_path', function( string $path, string $relative, array $ctx ) {
    if ( $relative === 'emails/weekly-recap.php' ) {
        return MY_PLUGIN_PATH . 'custom-templates/recap.php';
    }
    return $path;
}, 10, 3 );

Note: Block render PHP (src/Blocks/<slug>/render.php) is not theme-overridable - Gutenberg's block API doesn't permit it. Use wb_gam_block_<slug>_data to mutate input data, or wb_gam_block_after_render to inject HTML.

REST API Reference

Base URL: /wp-json/wb-gamification/v1/

Authentication

Two methods are supported:

Method How When to use
Cookie + nonce Standard X-WP-Nonce header Same-site JavaScript requests
API key X-WB-Gam-Key header or ?api_key= query param Remote sites, mobile apps, Zapier/Make

See Cross-Site API for API key creation and remote site setup.


Members Controller

GET /members/{id}

Full gamification profile for one member.

Permission: Public (unauthenticated returns public data). Self or admin returns full private data.

Response:

{
  "id": 42,
  "display_name": "Jane Smith",
  "avatar_url": "https://...",
  "points": 1250,
  "level": {
    "id": 3,
    "name": "Contributor",
    "min_points": 500,
    "progress_pct": 75,
    "next_threshold": 1500,
    "next_level_name": "Regular"
  },
  "badges_count": 8,
  "preferences": {
    "show_rank": true,
    "leaderboard_opt_out": false,
    "notification_mode": "smart"
  }
}

GET /members/{id}/points

Paginated points history for a member.

Query parameters:

Parameter Type Default Description
page int 1 Page number
per_page int 20 Rows per page (max 100)

Response headers: X-WP-Total, X-WP-TotalPages

Response body:

{
  "total": 1250,
  "history": [
    { "id": 99, "event_id": "uuid", "action_id": "publish_post", "points": 10, "object_id": 55, "created_at": "2026-03-18 12:00:00" }
  ]
}

GET /members/{id}/level

Current level and full level ladder with progress.

GET /members/{id}/badges

All badges earned by the member, ordered by earned_at DESC.

GET /members/{id}/events

Paginated raw event log. Parameters: page, per_page (max 100).

GET /members/{id}/streak

Streak data with optional contribution heatmap.

Parameter Type Default Description
heatmap_days int 0 Include N days of contribution data. 0 = skip

GET /members/me/toasts

Read and flush pending toast notifications for the current user. Requires authentication.


Points Controller

POST /points/award

Manually award points to a member. Bypasses cooldown and cap checks.

Permission: manage_options or wb_gam_award_manual

Body:

Field Type Required Description
user_id int Yes Target user ID
points int Yes Points to award (1-100,000)
reason string No Action ID label. Default: manual_award
note string No Admin note stored in event metadata

Response (201):

{ "awarded": true, "user_id": 42, "points": 100, "reason": "manual_award" }

DELETE /points/{id}

Revoke a specific points ledger row. The event record is preserved (events are immutable); only the points side-effect is removed.

Permission: manage_options

Response:

{ "deleted": true, "id": 99, "user_id": 42, "points": 10 }

Badges Controller

GET /badges

All badge definitions with optional earned status and rarity scores.

Parameter Type Default Description
user_id int current user Include earned status for this user. 0 = skip
category string - Filter by category slug

Permission: Public

GET /badges/{id}

Single badge definition with rarity percentage and earner count.

Permission: Public

PUT /badges/{id}

Update badge definition fields (name, description, image_url, category).

Permission: manage_options

DELETE /badges/{id}

Delete a badge definition. Cascades to wb_gam_user_badges and associated rules.

Permission: manage_options

POST /badges/{id}/award

Manually award a badge to a user.

Permission: manage_options

Body: { "user_id": 42 }

Response:

{ "awarded": true, "badge_id": "top_contributor", "user_id": 42, "message": "Badge awarded successfully." }

Leaderboard Controller

GET /leaderboard

Top-N members for a given period.

Permission: Public. Opt-out members excluded from results.

Parameter Type Default Description
period string all all, month, week, day
limit int 10 1-100
scope_type string - Scope type (e.g. bp_group)
scope_id int 0 Scope object ID

Response:

{
  "period": "week",
  "scope": { "type": "", "id": 0 },
  "rows": [
    { "rank": 1, "user_id": 42, "display_name": "Jane Smith", "avatar_url": "https://...", "points": 320 }
  ]
}

GET /leaderboard/group/{group_id}

BuddyPress group-scoped leaderboard. Accepts same period and limit params.

GET /leaderboard/me

Current user's private rank (visible even when opted out of public display).

Permission: Must be logged in


Kudos Controller

GET /kudos

Recent kudos feed.

Parameter Type Default Description
limit int 20 Max entries (1-50)

Permission: Public

POST /kudos

Give kudos to another member.

Permission: Must be logged in

Body:

Field Type Required Description
receiver_id int Yes User ID of recipient
message string No Optional message (max 255 chars)

Response (201):

{ "success": true, "receiver_id": 55, "daily_remaining": 4 }

GET /kudos/me

Current user's kudos stats: received_total, daily_limit, sent_today, daily_remaining.

Permission: Must be logged in


Actions Controller

GET /actions

All registered gamification actions with labels, categories, point values, and enabled state.

Permission: manage_options


Challenges Controller

Endpoints follow the pattern /challenges and /challenges/{id}. Full documentation at /wp-json/wb-gamification/v1/challenges schema endpoint.


Events Controller

GET /events

Site-wide event log with filtering. Admin only.

Permission: manage_options


Webhooks Controller

GET /webhooks

List registered webhook endpoints.

Permission: manage_options

POST /webhooks

Register a new webhook.

Body: { "url": "https://...", "secret": "...", "events": ["points_awarded", "badge_awarded"] }

DELETE /webhooks/{id}

Delete a webhook registration.


Rules Controller

Manage stored rule configurations (badge conditions, point multipliers).

Permission: manage_options for all write operations.


Credential Controller (OpenBadges 3.0)

GET /credentials/{badge_id}/{user_id}

Returns an OpenBadges 3.0 JSON-LD document. This endpoint is public - no authentication required - so credential URLs can be verified by LinkedIn and other services.

Returns HTTP 410 Gone for expired credentials.

{
  "@context": ["https://www.w3.org/2018/credentials/v1", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"],
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "issuer": { "id": "https://example.com", "name": "My Community" },
  "credentialSubject": {
    "id": "https://example.com/members/jane-smith/",
    "achievement": { "name": "Top Contributor", "description": "..." }
  }
}

Redemption Controller

Endpoints for the rewards store: list items, redeem points, view redemption history.

Permission: Authenticated members can redeem. manage_options for catalog management.


Recap Controller

Year-in-review data for a member or site-wide.


Badge Share Controller

Public badge share page data (OG metadata for social sharing).


Levels Controller

GET /levels

All configured levels with thresholds and icons.


Capabilities Controller

GET /capabilities

Discovery endpoint for mobile apps and remote sites. Returns authentication status, permissions map, feature flags, plugin version, and all endpoint URLs.

Permission: Public

{
  "authenticated": true,
  "user_id": 42,
  "site_id": "",
  "mode": "local",
  "can": {
    "read_leaderboard": true,
    "award_points": false,
    "give_kudos": true
  },
  "features": { "cohort_leagues": false },
  "version": "1.0.0",
  "endpoints": {
    "members": "https://example.com/wp-json/wb-gamification/v1/members",
    "leaderboard": "https://example.com/wp-json/wb-gamification/v1/leaderboard"
  }
}

Error Responses

All errors use the standard WordPress REST error format:

{
  "code": "rest_forbidden",
  "message": "You do not have permission to manage points.",
  "data": { "status": 403 }
}
Status Meaning
400 Bad request - missing or invalid parameters
401 Not authenticated
403 Insufficient capability
404 Resource not found
410 Gone - credential has expired
422 Unprocessable - business rule violation (e.g. kudos daily limit)

Manifest Files

How Manifests Work

Any WordPress plugin can award gamification points without depending on WB Gamification at runtime. Create a file named wb-gamification.php in your plugin's root directory. The file returns a plain PHP array. WB Gamification discovers and loads it automatically at plugins_loaded priority 5 - before any hooks fire.

If WB Gamification is not installed, your manifest file is simply never loaded. No dependency errors, no fatal calls.

File Location

your-plugin/
├── your-plugin.php        (main plugin file)
└── wb-gamification.php    (gamification manifest)

Manifest Structure

<?php
/**
 * WB Gamification manifest for My Plugin.
 *
 * This file is auto-discovered by WB Gamification at plugins_loaded priority 5.
 * It is safe to ship in the free version - WB Gamification is an optional dependency.
 */
return [
    'plugin'   => 'my-plugin',          // Used in Registry collision reports.
    'version'  => '1.0.0',              // Your plugin version (informational).
    'triggers' => [
        // Each array in 'triggers' is a gamification action definition.
        [
            'id'                  => 'my_plugin_action',
            'label'               => 'Did Something',
            'description'         => 'Awarded when a member does something in My Plugin.',
            'hook'                => 'my_plugin_action_hook',
            'user_callback'       => function( $user_id, $data ) { return $user_id; },
            'metadata_callback'   => function( $user_id, $data ) { return [ 'item_id' => $data->id ]; },
            'default_points'      => 10,
            'category'            => 'my_plugin',
            'icon'                => 'dashicons-star-filled',
            'repeatable'          => true,
            'cooldown'            => 3600,
            'daily_cap'           => 5,
            'async'               => false,
            'standalone_only'     => false,
            'requires_buddypress' => false,
        ],
    ],
];

Trigger Field Reference

Field Type Required Description
id string Yes Unique action identifier. Use plugin_name_action format to avoid collisions
label string Yes Human-readable label shown in the admin actions list
description string No Longer description shown in tooltips and the setup wizard
hook string Yes WordPress action hook name to listen on
user_callback callable Yes Receives the hook arguments. Must return the WordPress user ID to award points to
metadata_callback callable No Receives the hook arguments. Returns an array merged into event metadata (available in wb_gam_points_for_action filter)
default_points int Yes Default points awarded. Admins can override this in the settings UI
category string No Category slug for grouping in the admin UI (e.g. buddypress, woocommerce)
icon string No Dashicon class (e.g. dashicons-heart) for the admin UI
repeatable bool No Whether the action can be awarded more than once. Default true
cooldown int No Minimum seconds between repeated awards for the same user. 0 = no cooldown
daily_cap int No Maximum awards per calendar day per user. 0 = unlimited
async bool No Route through Action Scheduler instead of processing synchronously. Use for high-volume events
standalone_only bool No Set true to skip this trigger when BuddyPress is active (because BP's own hooks cover the same event better)
requires_buddypress bool No Set true to only register this trigger when BuddyPress is active

Complete Working Example

This example awards points when a member submits a contact form in a fictional forms plugin, with a daily cap and metadata enrichment:

<?php
return [
    'plugin'   => 'my-forms-plugin',
    'version'  => '2.1.0',
    'triggers' => [
        // Award points for submitting any form.
        [
            'id'              => 'my_forms_submission',
            'label'           => 'Submitted a Form',
            'description'     => 'Awarded each time a member submits a form.',
            'hook'            => 'my_forms_submission_complete',
            'user_callback'   => function( $form_id, $user_id ) {
                return (int) $user_id;
            },
            'metadata_callback' => function( $form_id, $user_id ) {
                return [ 'form_id' => (int) $form_id ];
            },
            'default_points'  => 5,
            'category'        => 'forms',
            'icon'            => 'dashicons-feedback',
            'repeatable'      => true,
            'cooldown'        => 0,
            'daily_cap'       => 3,
            'async'           => false,
        ],

        // Award a one-time bonus for the first form submission.
        [
            'id'              => 'my_forms_first_submission',
            'label'           => 'First Form Submission',
            'description'     => 'One-time bonus for a member\'s very first form submission.',
            'hook'            => 'my_forms_submission_complete',
            'user_callback'   => function( $form_id, $user_id ) {
                return (int) $user_id;
            },
            'default_points'  => 25,
            'category'        => 'forms',
            'repeatable'      => false,   // Only once per member.
            'cooldown'        => 0,
            'daily_cap'       => 0,
            'async'           => false,
        ],

        // BP-only trigger: award points for form submissions inside a group.
        [
            'id'                  => 'my_forms_group_submission',
            'label'               => 'Submitted a Group Form',
            'description'         => 'Awarded when a member submits a form inside a BuddyPress group.',
            'hook'                => 'my_forms_group_submission_complete',
            'user_callback'       => function( $form_id, $user_id, $group_id ) {
                return (int) $user_id;
            },
            'default_points'      => 8,
            'category'            => 'forms',
            'repeatable'          => true,
            'cooldown'            => 3600,
            'daily_cap'           => 5,
            'requires_buddypress' => true,  // Only registers when BP is active.
        ],
    ],
];

Conditional Triggers: standalone_only and requires_buddypress

These two flags let you ship one manifest that works correctly in both BuddyPress and non-BuddyPress environments.

Scenario: Your plugin fires my_plugin_post_published. When WordPress is running standalone, you want to award points for it. But when BuddyPress is active, the BuddyPress bp_publish_post integration already covers this event more richly - so you want to skip your version.

[
    'id'              => 'my_plugin_post_published_standalone',
    'hook'            => 'my_plugin_post_published',
    'standalone_only' => true,   // Skip when BuddyPress is active.
    // ...
],
[
    'id'                  => 'my_plugin_post_published_bp',
    'hook'                => 'my_plugin_post_published',
    'requires_buddypress' => true,   // Only register when BuddyPress is active.
    // ...
],

Both flags are stripped from the trigger before it is passed to Registry::register_action().

Registering Actions Programmatically

You can also call the PHP helper directly instead of using a manifest file. This is useful when your trigger logic is complex enough to warrant a full class:

add_action( 'wb_gam_register', function() {
    wb_gam_register_action( [
        'id'             => 'my_plugin_action',
        'label'          => 'My Action',
        'hook'           => 'my_plugin_hook',
        'user_callback'  => fn( $user_id ) => $user_id,
        'default_points' => 10,
        'category'       => 'my_plugin',
        'repeatable'     => true,
        'cooldown'       => 0,
        'daily_cap'      => 0,
    ] );
} );

This fires after Registry::init() at plugins_loaded priority 6.

Validation

The ManifestLoader validates every manifest and trigger at load time:

  1. Manifest must return an array. If the file does not return array( ... ), it is skipped. When WP_DEBUG is enabled, a message is logged to debug.log.
  2. Each trigger must include id, hook, and default_points. Missing any of these causes the trigger to be skipped with a debug log entry identifying the file and missing key.

This means you can ship a manifest confidently - malformed entries are silently ignored in production and loudly reported during development.

Developer Hooks

wb_gam_manifest_paths (filter)

Add custom directories for the manifest scanner. The ManifestLoader scans every directory in this array for *.php files:

add_filter( 'wb_gam_manifest_paths', function ( array $paths ): array {
    $paths[] = get_stylesheet_directory() . '/gamification/';
    return $paths;
} );

wb_gam_manifests_loaded (action)

Fires after all manifests have been loaded and validated. Receives the complete array of action definitions:

add_action( 'wb_gam_manifests_loaded', function ( array $actions ): void {
    error_log( 'WB Gamification loaded ' . count( $actions ) . ' manifest actions.' );
} );

Quick Start

New to manifest files? Follow the Build Your First Integration tutorial to create a working manifest in 5 minutes.

Build Your First Integration

Add gamification to your WordPress plugin in 5 minutes. No PHP dependency on WB Gamification is required - your manifest file is silently ignored when the plugin is not installed.


Step 1: Create the manifest file

Create a file named wb-gamification.php in your plugin's root directory:

your-plugin/
├── your-plugin.php        (main plugin file)
└── wb-gamification.php    (gamification manifest)

Paste the following into wb-gamification.php and customise it:

<?php
/**
 * WB Gamification manifest for My Reviews Plugin.
 */

defined( 'ABSPATH' ) || exit;

return array(
    'plugin'   => 'my-reviews-plugin',
    'version'  => '1.0.0',
    'triggers' => array(

        // Award 10 points every time a member submits a review.
        array(
            'id'             => 'my_reviews_submitted',
            'label'          => 'Submitted a Review',
            'description'    => 'Awarded each time a member publishes a product review.',
            'hook'           => 'my_reviews_after_submit',
            'user_callback'  => function ( $review_id, $user_id ) {
                return (int) $user_id;
            },
            'default_points' => 10,
            'category'       => 'reviews',
            'icon'           => 'dashicons-star-half',
            'repeatable'     => true,
            'cooldown'       => 3600,   // One review per hour max.
            'daily_cap'      => 3,      // Up to 3 reviews per day.
        ),

        // One-time 50-point bonus for the very first review.
        array(
            'id'             => 'my_reviews_first_review',
            'label'          => 'First Review Bonus',
            'description'    => 'One-time bonus when a member submits their first review.',
            'hook'           => 'my_reviews_after_submit',
            'user_callback'  => function ( $review_id, $user_id ) {
                return (int) $user_id;
            },
            'default_points' => 50,
            'category'       => 'reviews',
            'repeatable'     => false,
        ),
    ),
);

Required fields

Every trigger must include these three keys or it will be skipped:

Key Type Description
id string Unique action identifier. Use a plugin_action naming convention
hook string The WordPress action hook that fires when the event occurs
default_points int Default points awarded. Admins can override this in the settings UI

See the Manifest Files reference for the full list of optional fields (user_callback, metadata_callback, cooldown, daily_cap, async, etc.).


Step 2: Activate both plugins

  1. Install and activate WB Gamification.
  2. Install and activate your plugin.

WB Gamification scans every active plugin directory for a wb-gamification.php file at plugins_loaded priority 5. No registration code is needed.


Step 3: Verify

  1. Go to WP Admin > Gamification > Settings > Points tab.
  2. Your custom actions should appear in the actions list with their default point values.
  3. Trigger the action (e.g. submit a review) and confirm points are awarded.

You can also verify via WP-CLI:

wp wb-gamification actions list

Advanced: Programmatic registration

If your trigger logic is too complex for a static manifest, register actions programmatically from your plugin's functions.php or a class constructor:

add_action( 'wb_gam_register', function () {
    if ( ! function_exists( 'wb_gam_register_action' ) ) {
        return;
    }

    wb_gam_register_action( array(
        'id'             => 'my_reviews_submitted',
        'label'          => 'Submitted a Review',
        'hook'           => 'my_reviews_after_submit',
        'user_callback'  => function ( $review_id, $user_id ) {
            return (int) $user_id;
        },
        'default_points' => 10,
        'category'       => 'reviews',
        'repeatable'     => true,
        'cooldown'       => 3600,
        'daily_cap'      => 3,
    ) );
} );

The wb_gam_register action fires at plugins_loaded priority 6, after all manifests have been loaded.


Available developer hooks

wb_gam_manifest_paths (filter)

Add custom directories for the manifest scanner to check. Useful if you store manifests in a theme or mu-plugin:

add_filter( 'wb_gam_manifest_paths', function ( array $paths ): array {
    $paths[] = get_stylesheet_directory() . '/gamification/';
    return $paths;
} );

wb_gam_manifests_loaded (action)

Fires after all manifest files have been loaded and validated. Receives the full array of discovered action definitions:

add_action( 'wb_gam_manifests_loaded', function ( array $actions ): void {
    // Log how many actions were discovered.
    error_log( 'WB Gamification loaded ' . count( $actions ) . ' manifest actions.' );
} );

Validation and debugging

When WP_DEBUG is enabled, the ManifestLoader logs warnings for:

  • Manifest files that do not return an array - check that your file ends with return array( ... );
  • Triggers missing required keys (id, hook, default_points) - the trigger is skipped and a message is logged with the file path and missing key name

Check your debug log at wp-content/debug.log to diagnose manifest issues.


Next steps

WP-CLI Commands

All commands use the wb-gamification command namespace:

wp wb-gamification <command> <subcommand> [options]

points award

Award points to a member. This is a direct admin award - it bypasses cooldown and daily-cap checks.

Syntax

wp wb-gamification points award --user=<id> --points=<n> [--action=<id>] [--message=<msg>]

Options

Option Required Description
--user=<id> Yes User ID, login name, or email address
--points=<n> Yes Number of points to award (positive integer)
--action=<id> No Action ID to record in the ledger. Default: manual
--message=<msg> No Optional admin note stored in event metadata

Examples

# Award 100 points to user ID 42.
wp wb-gamification points award --user=42 --points=100

# Award 50 points with a custom action ID and note.
wp wb-gamification points award --user=jane --points=50 --action=speaker_bonus --message="Community hero this month"

# Award by email address.
wp wb-gamification points award --user=jane@example.com --points=200

Expected Output

Success: Awarded 100 pts to Jane Smith. New total: 1350.
Success: Awarded 50 pts to Jane Smith (Community hero this month). New total: 1400.

member status

Show a member's full gamification profile: points, level, progress to the next level, and earned badges.

Syntax

wp wb-gamification member status --user=<id>

Options

Option Required Description
--user=<id> Yes User ID, login name, or email address

Examples

wp wb-gamification member status --user=42
wp wb-gamification member status --user=jane@example.com

Expected Output

User:    Jane Smith (ID: 42)
Points:  1350
Level:   Contributor
Next:    Regular (1500 pts) - 90% there
Badges:  4
         century_club, welcome, first_post, first_update

actions list

List all registered gamification actions with their current point values, daily cap, cooldown, and enabled state.

Syntax

wp wb-gamification actions list [--format=<format>] [--category=<cat>]

Options

Option Required Description
--format=<format> No Output format: table, csv, json, count. Default: table
--category=<cat> No Filter by category slug (e.g. buddypress, wordpress, commerce)

Examples

# Table output (default).
wp wb-gamification actions list

# JSON output for scripting.
wp wb-gamification actions list --format=json

# Filter to BuddyPress actions only.
wp wb-gamification actions list --category=buddypress

Expected Output (table)

+------------------------+-----------------------------+------------+--------+-----------+----------+---------+
| id                     | label                       | category   | points | daily_cap | cooldown | enabled |
+------------------------+-----------------------------+------------+--------+-----------+----------+---------+
| bp_activity_update     | Posted an activity update   | buddypress | 5      | 10        | -        | yes     |
| bp_friends_accepted    | Made a new friend           | buddypress | 10     | ∞         | -        | yes     |
| publish_post           | Published a post            | wordpress  | 15     | ∞         | -        | yes     |
+------------------------+-----------------------------+------------+--------+-----------+----------+---------+

logs prune

Remove old entries from the event log (wb_gam_events). The points ledger, badges, levels, and leaderboard are not affected - only the raw audit trail is trimmed.

Syntax

wp wb-gamification logs prune --before=<timespan> [--dry-run]

Options

Option Required Description
--before=<timespan> Yes Delete entries older than this. Formats: 6months, 1year, 90days
--dry-run No Show the row count that would be deleted without deleting anything

Examples

# Preview: how many rows would be deleted?
wp wb-gamification logs prune --before=6months --dry-run

# Delete entries older than one year.
wp wb-gamification logs prune --before=1year

# Delete entries older than 90 days.
wp wb-gamification logs prune --before=90days

Expected Output

[dry-run] Would delete 4,832 event log entries older than 2025-10-01 00:00:00.
Success: Deleted 4,832 event log entries older than 2025-10-01 00:00:00.

export user

Export all gamification data for a member as JSON. Use for GDPR data portability requests.

Syntax

wp wb-gamification export user --user=<id> [--format=<fmt>]

Options

Option Required Description
--user=<id> Yes User ID, login name, or email address
--format=<fmt> No Only json is supported. Default: json

Examples

# Print JSON to stdout.
wp wb-gamification export user --user=42

# Redirect to a file for delivery to the member.
wp wb-gamification export user --user=jane@example.com > export.json

Expected Output

{
  "user_id": 42,
  "display_name": "Jane Smith",
  "email": "jane@example.com",
  "exported_at": "2026-04-01T09:00:00+00:00",
  "points_total": 1350,
  "points_history": [...],
  "badges": [...],
  "level": { "id": 3, "name": "Contributor", "min_points": 500 }
}

doctor

Run a comprehensive system health check. Validates database tables, default levels, default badges, registered actions, settings, cron jobs, REST API routes, and pro addon compatibility. Reports pass/warn/fail for each check.

Syntax

wp wb-gamification doctor [--verbose] [--fix]

Options

Option Required Description
--verbose No Show details for passing checks, not just warnings and failures
--fix No Auto-fix issues that can be repaired (re-seed levels, badges; clean up orphaned options)

Examples

# Standard check.
wp wb-gamification doctor

# Show all check results including passing ones.
wp wb-gamification doctor --verbose

# Auto-fix what can be fixed.
wp wb-gamification doctor --fix

Expected Output

WB Gamification Doctor v1.0.0
────────────────────────────────────────────────────────────

► Database Tables
  ✓ 20 tables present
  ✓ DB version: 1.0.0

► Default Levels
  ✓ 5 levels defined
  ✓ Starting level (0 points) exists

► Default Badges
  ✓ 30 badges defined
  ✓ 23 badges with auto-award conditions

► Registered Actions
  ✓ 14 actions registered
  ✓ All actions enabled

► REST API
  ✓ 42 REST routes registered
  ✓ All core endpoints present

► Cron Jobs
  ⚠ Log pruner (wb_gam_prune_logs) not scheduled

────────────────────────────────────────────────────────────
Results: 18 pass, 1 warn, 0 fail
Warning: Plugin has warnings - review before release.

The --fix flag re-seeds missing levels and badges by running Installer::install(), and cleans up any orphaned option keys from previous plugin versions.

Helper Functions

All functions are defined in src/Extensions/functions.php and available globally once WB Gamification is active. No use statement or class prefix is needed.


Action Registration

wb_gam_register_action( array $args ): void

Register a custom action that awards points when a WordPress hook fires. Routes directly to Registry::register_action().

Parameter Type Required Description
$args['id'] string Yes Unique action identifier
$args['label'] string Yes Human-readable label
$args['description'] string No Optional description
$args['hook'] string Yes WordPress hook name
$args['user_callback'] callable Yes Returns the user ID from hook arguments
$args['default_points'] int Yes Default points awarded
$args['category'] string No Category slug
$args['icon'] string No Dashicon class
$args['repeatable'] bool No Allow multiple awards. Default true
$args['cooldown'] int No Seconds between awards. 0 = none
$args['daily_cap'] int No Max awards per day. 0 = unlimited
$args['weekly_cap'] int No Max awards per week. 0 = unlimited
add_action( 'wb_gam_register', function() {
    wb_gam_register_action( [
        'id'             => 'my_plugin_signup',
        'label'          => 'Signed up via My Plugin',
        'hook'           => 'my_plugin_user_signup',
        'user_callback'  => fn( $user_id ) => $user_id,
        'default_points' => 50,
        'category'       => 'my_plugin',
        'repeatable'     => false,
    ] );
} );

wb_gam_register_badge_trigger( array $args ): void

Register a custom badge trigger condition. Routes to Registry::register_badge_trigger().

Parameter Type Required Description
$args['id'] string Yes Unique trigger identifier
$args['label'] string Yes Human-readable label
$args['hook'] string Yes WordPress hook to listen on
$args['condition'] callable Yes Returns true when the badge should be awarded

wb_gam_register_challenge_type( array $args ): void

Register a custom challenge type. Routes to Registry::register_challenge_type().

Parameter Type Required Description
$args['id'] string Yes Unique challenge type identifier
$args['label'] string Yes Human-readable label
$args['action_id'] string Yes Action ID this challenge tracks
$args['countable'] bool No Whether progress is tracked by count

Points Functions

wb_gam_get_user_points( int $user_id ): int

Get the total accumulated points for a user. Reads from the object cache first; falls back to a SUM query on wb_gam_points.

$points = wb_gam_get_user_points( get_current_user_id() );
echo "You have {$points} points.";

wb_gam_award_points( int $user_id, int $points, string $action_id = 'manual', int $object_id = 0 ): bool

Award points to a user manually. Bypasses cooldown and cap checks. Routes through Engine::process() so the event is persisted and all hooks fire normally.

Returns false if $points <= 0 or $user_id <= 0.

Parameter Type Default Description
$user_id int - WordPress user ID
$points int - Points to award (must be > 0)
$action_id string 'manual' Action ID logged against the points row
$object_id int 0 Optional related object (e.g. post ID)
// Award 100 bonus points.
$awarded = wb_gam_award_points( $user_id, 100, 'promo_bonus' );

if ( $awarded ) {
    // Points were written and hooks fired.
}

wb_gam_get_user_action_count( int $user_id, string $action_id ): int

Get how many times a specific action has been awarded to a user.

$post_count = wb_gam_get_user_action_count( $user_id, 'publish_post' );
if ( $post_count >= 10 ) {
    // User is a prolific writer.
}

Badge Functions

wb_gam_has_badge( int $user_id, string $badge_id ): bool

Check whether a user currently holds a specific badge. Respects expiry - expired badges return false.

if ( wb_gam_has_badge( $user_id, 'top_contributor' ) ) {
    // Show a special UI element.
}

wb_gam_get_user_badges( int $user_id ): array

Get all badges currently held by a user as an array of badge data rows. Expired badges are excluded.

$badges = wb_gam_get_user_badges( $user_id );
foreach ( $badges as $badge ) {
    echo $badge['name'] . ' - earned ' . $badge['earned_at'];
}

Level Functions

wb_gam_get_user_level( int $user_id ): ?array

Get the current level for a user. Returns null if no level threshold has been met.

Return shape: array{ id: int, name: string, min_points: int } or null

$level = wb_gam_get_user_level( $user_id );
if ( $level ) {
    echo "Level: " . $level['name'];
}

Streak Functions

wb_gam_get_user_streak( int $user_id ): array

Get a user's current streak data.

Return shape: array{ current_streak: int, longest_streak: int, last_active: string }

$streak = wb_gam_get_user_streak( $user_id );
echo "Current streak: {$streak['current_streak']} days";
echo "Best streak: {$streak['longest_streak']} days";

Leaderboard Functions

wb_gam_get_leaderboard( string $period = 'all', int $limit = 10 ): array

Get the leaderboard for a given period. Reads from wb_gam_leaderboard_cache for performance.

Parameter Type Default Description
$period string 'all' 'all', 'week', 'month', 'day'
$limit int 10 Number of entries to return
$top_10 = wb_gam_get_leaderboard( 'week', 10 );
foreach ( $top_10 as $row ) {
    printf( "#%d: %s - %d pts\n", $row['rank'], $row['display_name'], $row['points'] );
}

Feature Flags

wb_gam_is_feature_enabled( string $feature ): bool

Check whether a feature flag is currently enabled. Reads from WBGam\Engine\FeatureFlags.

if ( wb_gam_is_feature_enabled( 'cohort_leagues' ) ) {
    // Show cohort league UI.
}

Common feature flags: cohort_leagues, weekly_email, cosmetics, redemption_store, site_first_badges.

Cross-Site API

Overview

WB Gamification can act as a centralized gamification server. A dedicated WordPress site runs the plugin and holds all gamification data. Remote sites - BuddyPress communities, WooCommerce stores, headless frontends, mobile apps - authenticate via API keys and submit events to the central server.

This model is useful when you run multiple sites and want a single leaderboard, unified badge library, and one admin interface.

Deployment Modes

Mode How When to use
Local Plugin installed on the same site. Uses WordPress cookie/nonce auth Single-site installs, the default
Remote Plugin on a dedicated gamification center site. Remote clients authenticate via X-WB-Gam-Key Multi-site setups, mobile apps, external services

In remote mode the capabilities response includes "mode": "remote" and "site_id" is populated for all events.

Creating API Keys

API keys are created and managed at WP Admin → Gamification → API Keys. Each key is associated with a WordPress user (whose capabilities determine what the key can do) and optionally a site_id string for attribution.

You can also create keys programmatically:

use WBGam\API\ApiKeyAuth;

$key = ApiKeyAuth::create_key(
    label:   'My Remote Store',     // Human-readable label shown in admin.
    user_id: 1,                     // User whose capabilities the key inherits.
    site_id: 'my-store'             // Identifier embedded in all events from this key.
);

// $key = 'wbgam_AbCdEfGhIjKlMnOpQrStUvWxYz...' (40-char random string)

Keys start with wbgam_. Store them securely - they cannot be retrieved after creation.

Revoking and Deleting Keys

// Deactivate (keeps the key record for audit purposes).
ApiKeyAuth::revoke_key( 'wbgam_...' );

// Permanently delete.
ApiKeyAuth::delete_key( 'wbgam_...' );

Authenticating Requests

Include the API key in every request to the gamification center.

Option 1: HTTP Header (recommended)

GET /wp-json/wb-gamification/v1/members/42
X-WB-Gam-Key: wbgam_AbCdEfGhIjKlMnOpQrStUvWxYz...

Option 2: Query Parameter

GET /wp-json/wb-gamification/v1/members/42?api_key=wbgam_AbCdEfGhIjKlMnOpQrStUvWxYz...

The header approach is preferred - query params can appear in server logs.

Authentication Priority

API key auth runs at rest_authentication_errors priority 20, after WordPress's own cookie/nonce auth. If a valid cookie session already exists, the API key is ignored. This means the same endpoint works for both browser sessions and remote API callers.

Site ID Tracking

When a request is authenticated via an API key that has a site_id set, that value is injected into every event's metadata under the _site_id key and stored in the wb_gam_events.site_id column.

You can filter by site_id when querying the event log to audit activity per remote site.

The site_id is also exposed in the capabilities response so remote clients can confirm their identity:

{
  "authenticated": true,
  "mode": "remote",
  "site_id": "my-store",
  "can": { "submit_events": true, "award_points": false }
}

CORS Headers

When a request is authenticated via API key, the plugin automatically adds CORS headers allowing cross-origin requests:

Access-Control-Allow-Origin: <request origin>
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-WB-Gam-Key, Content-Type, Authorization, X-WP-Nonce
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS

This enables browser-based JavaScript on remote origins to call the gamification center directly.

Capabilities Discovery

Before making calls, a remote site should fetch the capabilities endpoint to learn what it is allowed to do:

GET /wp-json/wb-gamification/v1/capabilities
X-WB-Gam-Key: wbgam_...

Response:

{
  "authenticated": true,
  "user_id": 1,
  "site_id": "my-store",
  "mode": "remote",
  "can": {
    "read_leaderboard": true,
    "read_badges": true,
    "read_own_profile": true,
    "read_any_profile": false,
    "award_points": false,
    "submit_events": true,
    "give_kudos": true
  },
  "features": { "cohort_leagues": false, "redemption_store": true },
  "version": "1.0.0",
  "endpoints": {
    "members":     "https://gam.example.com/wp-json/wb-gamification/v1/members",
    "leaderboard": "https://gam.example.com/wp-json/wb-gamification/v1/leaderboard",
    "badges":      "https://gam.example.com/wp-json/wb-gamification/v1/badges",
    "kudos":       "https://gam.example.com/wp-json/wb-gamification/v1/kudos",
    "capabilities":"https://gam.example.com/wp-json/wb-gamification/v1/capabilities"
  }
}

Use the endpoints map to resolve URLs dynamically rather than hardcoding paths.

Connecting a Remote Site

  1. On the gamification center site, go to WP Admin → Gamification → API Keys and create a key. Set the Site ID field to something that identifies your remote site (e.g. store-site-1).

  2. Copy the generated key.

  3. On the remote site, install WB Gamification and add the key to your wp-config.php or your plugin's settings:

define( 'WB_GAM_REMOTE_CENTER_URL', 'https://gam.example.com' );
define( 'WB_GAM_REMOTE_API_KEY',    'wbgam_...' );
  1. Use the helper functions or REST API to forward events:
// Forward a points event to the central server.
$response = wp_remote_post(
    WB_GAM_REMOTE_CENTER_URL . '/wp-json/wb-gamification/v1/points/award',
    [
        'headers' => [
            'X-WB-Gam-Key' => WB_GAM_REMOTE_API_KEY,
            'Content-Type' => 'application/json',
        ],
        'body' => wp_json_encode( [
            'user_id' => $user_id,
            'points'  => 10,
            'reason'  => 'remote_purchase',
        ] ),
    ]
);

Multi-Site Use Case

Example architecture:

                ┌─────────────────────────────────┐
                │  gamification.example.com        │
                │  (WB Gamification center site)   │
                │  - All points, badges, levels    │
                │  - Single leaderboard            │
                │  - Admin dashboard               │
                └───────────┬─────────────────────┘
                            │ REST API + API keys
            ┌───────────────┼────────────────────┐
            │               │                    │
     community.example.com  store.example.com   app.example.com
     (BuddyPress)           (WooCommerce)       (React Native)
     site_id: "community"   site_id: "store"    site_id: "mobile"

Each remote site uses its own API key with a distinct site_id. The gamification center can filter its event log and analytics by site_id to see which site generated which activity.

Database Schema

All tables use the WordPress table prefix (default wp_). The current schema version is tracked by get_option('wb_gam_db_version').

Migrations live in src/Engine/DbUpgrader.php. Each version gets its own upgrade_to_X_Y_Z() method. Tables are created on activation via src/Engine/Installer.php using dbDelta().


Core Tables

wb_gam_events

Immutable event log. This is the source of truth for all gamification state. Events are never deleted except during GDPR erasure. All other tables are derived from this one and can be replayed.

Column Type Description
id VARCHAR(36) PK UUID generated at event creation time
user_id BIGINT UNSIGNED WordPress user ID
action_id VARCHAR(100) Action identifier (e.g. publish_post)
object_id BIGINT UNSIGNED NULL Optional related object (e.g. post ID)
metadata LONGTEXT JSON-encoded metadata bag (quality signals, word counts, etc.)
site_id VARCHAR(100) Remote site identifier for cross-site events (empty for local)
created_at DATETIME Event timestamp (UTC)

Indexes: idx_user_action (user_id, action_id), idx_user_created (user_id, created_at), idx_created (created_at), idx_site_id (site_id)

wb_gam_points

Points ledger. Derived from events. Each row represents one point award transaction and links back to the event that caused it via event_id.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT Ledger row ID
event_id VARCHAR(36) NULL FK to wb_gam_events.id
user_id BIGINT UNSIGNED WordPress user ID
action_id VARCHAR(100) Action identifier
points INT Points awarded (positive integer)
object_id BIGINT UNSIGNED NULL Optional related object
created_at DATETIME Transaction timestamp

Indexes: idx_event (event_id), idx_user_created (user_id, created_at), idx_user_action_created (user_id, action_id, created_at) (sargable for leaderboard queries), idx_action (action_id), idx_created (created_at)


Member Tables

wb_gam_user_badges

Earned badges. One row per member per badge. The UNIQUE KEY user_badge (user_id, badge_id) prevents duplicate awards.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
user_id BIGINT UNSIGNED WordPress user ID
badge_id VARCHAR(100) Badge identifier (FK to wb_gam_badge_defs.id)
earned_at DATETIME Award timestamp
expires_at DATETIME NULL Expiry timestamp (added v0.3.0). NULL = never expires

Indexes: UNIQUE user_badge (user_id, badge_id), idx_expires_at (expires_at)

wb_gam_levels

Level definitions. Configurable per community. Seeded with 5 default levels on fresh install.

Column Type Description
id INT UNSIGNED PK AUTO_INCREMENT
name VARCHAR(255) Display name (e.g. "Contributor")
min_points BIGINT UNSIGNED Minimum points required to reach this level
icon_url VARCHAR(500) NULL Optional level icon URL
sort_order INT Display order in admin UI

Index: min_points (min_points) - used in level-up queries

Default levels: Newcomer (0), Member (100), Contributor (500), Regular (1500), Champion (5000)

wb_gam_streaks

Streak state per member. One row per user, updated on every point-earning activity.

Column Type Description
user_id BIGINT UNSIGNED PK WordPress user ID
current_streak INT UNSIGNED Current consecutive day/week count
longest_streak INT UNSIGNED All-time best streak
last_active DATE Last date the member earned points
timezone VARCHAR(50) Member timezone for day boundary calculations. Default UTC
grace_used TINYINT(1) Whether the one-time grace day has been used
updated_at DATETIME Auto-updated on each write

wb_gam_member_prefs

Per-user notification and privacy preferences. One row per user; missing row = all defaults.

Column Type Default Description
user_id BIGINT UNSIGNED PK WordPress user ID
leaderboard_opt_out TINYINT(1) 0 1 = hidden from public leaderboard
show_rank TINYINT(1) 1 0 = hide rank badge on profile and directory
notification_mode VARCHAR(20) smart smart, all, none

Index: idx_opt_out (leaderboard_opt_out)


Engagement Tables

wb_gam_challenges

Individual challenge definitions.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
title VARCHAR(255) Challenge display name
type VARCHAR(20) individual or team
team_group_id BIGINT UNSIGNED NULL BuddyPress group ID (for team challenges)
action_id VARCHAR(100) Action this challenge tracks
target INT UNSIGNED Target count to complete the challenge
bonus_points INT Bonus points awarded on completion
period VARCHAR(20) none, day, week, month
starts_at DATETIME NULL Challenge start time
ends_at DATETIME NULL Challenge end time
status VARCHAR(20) active, inactive, completed

Indexes: status (status), idx_status_action (status, action_id)

wb_gam_challenge_log

Per-user challenge progress tracking.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
user_id BIGINT UNSIGNED
challenge_id BIGINT UNSIGNED
progress INT UNSIGNED Current progress count
completed_at DATETIME NULL When the challenge was completed
created_at DATETIME

Key: UNIQUE user_challenge (user_id, challenge_id)

wb_gam_kudos

Peer kudos log. One row per kudos transaction.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
giver_id BIGINT UNSIGNED User who gave kudos
receiver_id BIGINT UNSIGNED User who received kudos
message VARCHAR(255) NULL Optional message
created_at DATETIME

Indexes: giver_date (giver_id, created_at), receiver_id (receiver_id)

wb_gam_community_challenges

Community-wide (Pokémon GO-style) challenges where all members contribute to a shared goal.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
title VARCHAR(255)
description TEXT NULL
target_action VARCHAR(100) Action being counted site-wide
target_count BIGINT UNSIGNED Global target
global_progress BIGINT UNSIGNED Current community-wide count
bonus_points INT Points awarded to each contributor on completion
status VARCHAR(20) active, completed
starts_at DATETIME NULL
ends_at DATETIME NULL
completed_at DATETIME NULL

wb_gam_community_challenge_contributions

Per-user contribution counts for community challenges.

Column Type Description
challenge_id BIGINT UNSIGNED
user_id BIGINT UNSIGNED
contribution_count BIGINT UNSIGNED Number of qualifying actions this user performed

PK: (challenge_id, user_id)


Rules Tables

wb_gam_rules

All rule configurations: badge conditions, point multipliers, and other rule types.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
rule_type VARCHAR(50) badge_condition, point_multiplier, etc.
target_id VARCHAR(100) NULL Badge ID (for badge_condition) or other target
rule_config LONGTEXT JSON-encoded rule parameters
is_active TINYINT(1) 1 = active, 0 = disabled
created_at DATETIME

Indexes: rule_type (rule_type), target_id (target_id)

Badge condition types stored in rule_config.condition_type:

  • point_milestone - fires when total_points >= config.points
  • action_count - fires when a specific action has been performed N times
  • admin_awarded - no automatic condition; admin awards manually

wb_gam_badge_defs

Badge definitions (catalog). Award conditions live in wb_gam_rules.

Column Type Description
id VARCHAR(100) PK Badge identifier slug (e.g. top_contributor)
name VARCHAR(255) Display name
description TEXT NULL
image_url VARCHAR(500) NULL Badge image URL
is_credential TINYINT(1) 1 = issued as an OpenBadges 3.0 credential
validity_days INT UNSIGNED NULL Badge expiry in days. NULL = never expires
closes_at DATETIME NULL Date after which the badge can no longer be earned
max_earners INT UNSIGNED NULL Maximum members who can hold this badge
category VARCHAR(50) points, wordpress, buddypress, special
created_at DATETIME

Advanced Tables

wb_gam_webhooks

Registered outbound webhook endpoints.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
url VARCHAR(500) Webhook target URL
secret VARCHAR(255) HMAC-SHA256 signing secret
events TEXT JSON array of event types to forward
is_active TINYINT(1)
created_at DATETIME

wb_gam_redemption_items

Rewards catalog for the points redemption store.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
title VARCHAR(255) Reward display name
description TEXT NULL
points_cost INT UNSIGNED Points required to redeem
reward_type VARCHAR(50) e.g. coupon, download, manual
reward_config LONGTEXT NULL JSON-encoded reward delivery config
stock INT UNSIGNED NULL Available quantity. NULL = unlimited
is_active TINYINT(1)
created_at DATETIME

wb_gam_redemptions

Redemption transaction log.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
user_id BIGINT UNSIGNED
item_id BIGINT UNSIGNED
points_cost INT UNSIGNED Points deducted at time of redemption
status VARCHAR(30) pending, fulfilled, cancelled
coupon_code VARCHAR(100) NULL Generated coupon code if applicable
created_at DATETIME

wb_gam_cosmetics

Cosmetics catalog (profile frames, avatar overlays, etc.).

Column Type Description
id VARCHAR(100) PK Cosmetic identifier slug
name VARCHAR(255)
type VARCHAR(50) e.g. avatar_frame, profile_background
asset_url VARCHAR(500) NULL URL to the cosmetic asset
css_class VARCHAR(100) NULL CSS class applied to the member's profile
award_type VARCHAR(30) admin, milestone, purchase
cost INT UNSIGNED Points cost if award_type = purchase. 0 = free
is_active TINYINT(1)

wb_gam_user_cosmetics

Cosmetics owned by members.

Column Type Description
user_id BIGINT UNSIGNED
cosmetic_id VARCHAR(100)
is_active TINYINT(1) 1 = currently equipped
awarded_at DATETIME

PK: (user_id, cosmetic_id)

wb_gam_cohort_members

Cohort league tracking (Duolingo-style weekly leagues).

Column Type Description
user_id BIGINT UNSIGNED
cohort_id VARCHAR(50) Cohort group identifier
tier TINYINT UNSIGNED Current league tier
tier_end TINYINT UNSIGNED NULL Tier at end of week (set during resolution)
outcome VARCHAR(20) NULL promoted, demoted, retained
week VARCHAR(10) ISO week identifier (e.g. 2026-W14)
pts_start INT UNSIGNED Points at the start of the week

PK: (user_id, week)

wb_gam_leaderboard_cache

Leaderboard snapshot. Written by wb_gam_leaderboard_snapshot cron job; read by LeaderboardEngine. Note: rank is backtick-escaped because it is a MySQL 8.0 reserved word.

Column Type Description
id BIGINT UNSIGNED PK AUTO_INCREMENT
user_id BIGINT UNSIGNED
period VARCHAR(20) all, month, week, day
total_points BIGINT Points total for this period
rank INT UNSIGNED Position in the leaderboard
updated_at DATETIME Snapshot timestamp

Indexes: idx_period_rank (period, rank), idx_user_period (user_id, period)


Version Tracking

// Check current DB version.
$version = get_option( 'wb_gam_db_version', '0.0.0' );

// After Installer::install() or DbUpgrader, the version is set to WB_GAM_VERSION.
update_option( 'wb_gam_db_version', WB_GAM_VERSION );

Run wp wb-gamification doctor to check whether your database schema matches the installed plugin version.

Outbound Webhooks

WB Gamification can notify external services whenever gamification events occur. Configure a destination URL and subscribe to the events you care about -- the plugin sends an HMAC-signed JSON POST for every matching event.

Webhooks are ideal for connecting to automation platforms like Zapier, Make (Integromat), or n8n.


Supported Event Types

Event Fired When Key Data Fields
points_awarded A user earns points from any action action_id, event_id, points
badge_earned A badge rule is satisfied and awarded badge_id, badge_name
level_changed A user's level increases after earning points new_level_id, new_level_name, old_level_id, old_level_name
streak_milestone A user hits a streak milestone (7, 14, 30... days) streak_days
challenge_completed A user finishes an individual challenge challenge_id, challenge_name
kudos_given A user sends peer kudos receiver_id, message

Payload Format

Every webhook delivery is an HTTP POST with Content-Type: application/json. The body follows this structure:

{
  "event": "points_awarded",
  "site_url": "https://community.example.com",
  "timestamp": "2026-04-12T14:30:00Z",
  "user_id": 42,
  "user_email": "jane@example.com",
  "data": {
    "action_id": "bp_new_activity",
    "event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "points": 10
  }
}

Example Payloads per Event Type

badge_earned

{
  "event": "badge_earned",
  "site_url": "https://community.example.com",
  "timestamp": "2026-04-12T14:30:00Z",
  "user_id": 42,
  "user_email": "jane@example.com",
  "data": {
    "badge_id": "first_post",
    "badge_name": "First Post"
  }
}

level_changed

{
  "event": "level_changed",
  "site_url": "https://community.example.com",
  "timestamp": "2026-04-12T14:31:00Z",
  "user_id": 42,
  "user_email": "jane@example.com",
  "data": {
    "new_level_id": 3,
    "new_level_name": "Expert",
    "old_level_id": 2,
    "old_level_name": "Contributor"
  }
}

streak_milestone

{
  "event": "streak_milestone",
  "site_url": "https://community.example.com",
  "timestamp": "2026-04-12T08:00:00Z",
  "user_id": 42,
  "user_email": "jane@example.com",
  "data": {
    "streak_days": 30
  }
}

challenge_completed

{
  "event": "challenge_completed",
  "site_url": "https://community.example.com",
  "timestamp": "2026-04-12T16:45:00Z",
  "user_id": 42,
  "user_email": "jane@example.com",
  "data": {
    "challenge_id": 7,
    "challenge_name": "Week of Learning"
  }
}

kudos_given

{
  "event": "kudos_given",
  "site_url": "https://community.example.com",
  "timestamp": "2026-04-12T12:00:00Z",
  "user_id": 15,
  "user_email": "bob@example.com",
  "data": {
    "receiver_id": 42,
    "message": "Great contribution to the forum!"
  }
}

HMAC Signature Verification

Every delivery includes an X-WB-Gam-Signature header with the format:

X-WB-Gam-Signature: sha256=<hex-encoded HMAC-SHA256>

The HMAC is computed over the raw JSON body using the webhook secret as the key. Always verify the signature before processing the payload.

PHP Verification

$secret    = 'your_webhook_secret_here';
$payload   = file_get_contents( 'php://input' );
$header    = $_SERVER['HTTP_X_WB_GAM_SIGNATURE'] ?? '';
$expected  = 'sha256=' . hash_hmac( 'sha256', $payload, $secret );

if ( ! hash_equals( $expected, $header ) ) {
    http_response_code( 401 );
    exit( 'Invalid signature.' );
}

$data = json_decode( $payload, true );
// Process $data...

Node.js Verification

const crypto = require('crypto');

function verifyWebhook(req, secret) {
  const payload   = JSON.stringify(req.body);
  const signature = req.headers['x-wb-gam-signature'] || '';
  const expected  = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// Express middleware example
app.post('/webhook', express.json({ verify: (req, res, buf) => {
  req.rawBody = buf;
}}), (req, res) => {
  const payload   = req.rawBody.toString('utf8');
  const signature = req.headers['x-wb-gam-signature'] || '';
  const expected  = 'sha256=' + crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(payload, 'utf8')
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
    return res.status(401).send('Invalid signature');
  }

  console.log('Event:', req.body.event, 'User:', req.body.user_id);
  res.status(200).send('OK');
});

Python Verification

import hmac
import hashlib

def verify_webhook(body: bytes, header: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header)

Retry Behaviour

Failed deliveries (HTTP errors or status codes >= 400) are retried automatically up to 3 times using exponential back-off:

Attempt Delay
1st retry 2 minutes
2nd retry 4 minutes
3rd retry 8 minutes

Retries are scheduled via Action Scheduler, so they survive page loads and cron interruptions. After 3 failed retries the delivery is abandoned and logged.


Delivery Log

Every delivery attempt (success or failure) is recorded. You can inspect the log via the REST API:

GET /wp-json/wb-gamification/v1/webhooks/{id}/log

Response:

{
  "webhook_id": 1,
  "entries": [
    {
      "event": "points_awarded",
      "status_code": 200,
      "success": true,
      "timestamp": "2026-04-12 14:30:05"
    },
    {
      "event": "badge_earned",
      "status_code": 0,
      "success": false,
      "timestamp": "2026-04-12 14:29:58"
    }
  ],
  "count": 2
}

A status_code of 0 indicates a connection-level failure (DNS, timeout, etc.).

To clear the log:

DELETE /wp-json/wb-gamification/v1/webhooks/{id}/log

REST API Quick Reference

All endpoints require the manage_options capability (admin only).

Method Endpoint Description
GET /wb-gamification/v1/webhooks List all webhooks
POST /wb-gamification/v1/webhooks Register a new webhook
GET /wb-gamification/v1/webhooks/{id} Get a single webhook
PUT /wb-gamification/v1/webhooks/{id} Update a webhook
DELETE /wb-gamification/v1/webhooks/{id} Delete a webhook
GET /wb-gamification/v1/webhooks/{id}/log View delivery log
DELETE /wb-gamification/v1/webhooks/{id}/log Clear delivery log

Create Webhook

curl -X POST https://example.com/wp-json/wb-gamification/v1/webhooks \
  -H "Content-Type: application/json" \
  -H "X-WP-Nonce: YOUR_NONCE" \
  --cookie "wordpress_logged_in_xxx=..." \
  -d '{
    "url": "https://hooks.zapier.com/hooks/catch/123/abc/",
    "events": ["points_awarded", "badge_earned", "level_changed"]
  }'

The response includes the secret -- store it securely. It is only returned on creation.


Platform Setup Guides

Zapier

  1. Create a new Zap and choose Webhooks by Zapier as the trigger.
  2. Select Catch Hook and copy the webhook URL (starts with https://hooks.zapier.com/).
  3. In your WordPress admin, go to Gamification > Settings > API and register the webhook URL with your desired events.
  4. Copy the returned secret for signature verification (optional in Zapier but recommended).
  5. Send a test event from WB Gamification and check the Zap trigger for the payload.
  6. Add your action steps (send email, update Google Sheet, post to Slack, etc.).

Make (Integromat)

  1. Create a new Scenario and add a Webhooks > Custom Webhook module.
  2. Click Add to create a new webhook and copy the URL.
  3. Register the URL in WB Gamification with the events you want.
  4. Click Run once in Make, then trigger an event from your site.
  5. Make will detect the payload structure automatically. Map the fields to your next module.
  6. To verify signatures, use a Tools > Set variable module with sha256= + HMAC-SHA256 of the body, then compare with the X-WB-Gam-Signature header.

n8n

  1. Add a Webhook node to your workflow.
  2. Set the HTTP Method to POST and copy the production webhook URL.
  3. Register the URL in WB Gamification with your desired event subscriptions.
  4. To verify signatures, add a Code node after the Webhook node:
const crypto = require('crypto');
const secret  = $env.WEBHOOK_SECRET;
const payload = JSON.stringify($input.first().json);
const sig     = $input.first().headers['x-wb-gam-signature'];
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(payload).digest('hex');

if (sig !== expected) {
  throw new Error('Invalid webhook signature');
}

return $input.all();
  1. Connect subsequent nodes to process the event data (send notifications, update CRM, trigger workflows, etc.).

Headers Sent

Every webhook delivery includes these custom headers:

Header Value Purpose
Content-Type application/json Payload format
X-WB-Gam-Signature sha256=<hex> HMAC-SHA256 signature for verification
X-WB-Gam-Site https://your-site.com Origin site URL (useful for multi-site setups)

Something unclear? Open a support ticket →

Buy WB Gamification