LifterLMS Hooks and Filters: The Useful Ones, With Real Code
A practical reference to the LifterLMS hooks developers use most: enrollment, completion, quiz, order and registration actions, plus the filters that…
Read articleWhat the LifterLMS WP-CLI commands bundled with LifterLMS 10.x can do: list and create courses, read course structure and enrollments, manage add-ons and licenses, bulk-enroll students safely, and run background jobs from the command line.
If you manage LifterLMS sites for clients, or you have SSH access to your own server, the command line is often the fastest way to answer questions and make bulk changes. How many students are in this course? Which add-ons need updates on all twelve sites? Can we enroll these 300 people before Monday? LifterLMS WP-CLI support handles all three.
This guide is for developers and technical site managers. It covers which wp llms commands exist in LifterLMS 10.x, how they work under the hood, practical recipes, and the safety habits that stop a one-line command from becoming a very bad afternoon.
Commands were checked against the LifterLMS 10.3 source and the LifterLMS CLI command reference. You need WP-CLI installed on the server.
Since LifterLMS 10.1 the CLI is bundled in the core plugin; before that it was a separate download. There is nothing to install beyond WP-CLI itself. Run wp help llms to see the commands your version provides.
LifterLMS still labels the CLI a public beta and warns that commands may change without notice. Read the changelog before relying on a command in a scheduled script, and pin scripts to a tested LifterLMS version.
| Command | What it does |
|---|---|
wp llms version [<slug>] | Shows the LifterLMS version, or an add-on's version |
wp llms course, section, lesson | Course content |
wp llms membership, access-plan | Memberships and pricing |
wp llms student, instructor | People |
wp llms api-key | REST API keys |
wp llms course content <id> | The full outline of a course: sections and lessons in order (added in 10.1) |
wp llms course enrollments <id> | Students enrolled in a course, paginated (added in 10.1) |
wp llms addon | List, install, activate, deactivate, update and uninstall add-ons |
wp llms license | Activate, deactivate and list license keys |
The resource commands (course, lesson, student and so on) share the same subcommands: list, get, create, update, delete, plus diff, generate and edit. On 10.x you may also see commands for newer resources added to the REST API, such as webhooks and quizzes, because the command list is built from the API.
Most wp llms resource commands are generated from the LifterLMS REST API. When you run wp llms course list, the CLI makes an internal request to the same courses endpoint the API uses, with the same fields, validation and permission checks. Everything in our REST API introduction applies: the same field names, the same filters, the same results.
Two consequences matter:
--user, the CLI picks an administrator account to run as. Pass --user= explicitly in scripts so changes are attributable and permission checks reflect a real role.--per_page, --search, --status and --orderby are the API's collection parameters, with underscores as the API spells them.Read commands accept --format=table|json|csv|yaml|ids|count and --fields= to limit columns. Create, update and delete accept --porcelain, which prints only the ID so you can chain commands.
# Published courses: ID, title and URL only
wp llms course list --status=publish --fields=id,title,permalink --per_page=50 --format=json
# Search by title
wp llms course list --search="onboarding" --format=json
# The sections and lessons of course 42
wp llms course content 42 --format=json
# How many students are enrolled in course 42?
wp llms course enrollments 42 --format=count
# Enrollment rows as CSV, 100 per page
wp llms course enrollments 42 --per_page=100 --page=1 --format=csv > course-42.csv
COURSE_ID=$(wp llms course create --title="Safety Basics 2027" \
--content="Course description goes here." --status=draft --porcelain --user=admin)
echo "Created course $COURSE_ID"
Both --title and --content are required when creating a course. Build the sections and lessons in the course builder afterwards, or create them with wp llms section create and wp llms lesson create, which take the parent ID.
wp llms course delete 42 moves the course to the trash. Adding --force=true bypasses the trash. Take a database backup with wp db export before any bulk delete.
Three subcommands are less obvious than the rest:
generate creates test records, ten by default, with --count= to change that. wp llms course generate --count=5 --title="Test course" --content="Test" gives you five test courses for checking a catalog layout. Use it on staging only; it writes real posts.edit opens a record in your terminal's text editor as YAML, then saves your changes back through the API. It is handy for a quick fix to one field on a server without an admin login.diff is described in the reference as comparing records between environments, for example checking that staging and production have the same courses before a launch. Read its help with wp help llms course diff on your version before relying on it, as the CLI is still in beta.Every subcommand has built-in help listing its exact options, generated from the API schema: wp help llms lesson create shows every field a lesson accepts.
The CLI reference also lists students-enrollments and students-progress commands. Their routes need two IDs, the student and the course, so for scripts we prefer wp eval with LifterLMS's own enrollment function, which is simple to read and check. It runs the same code as any other enrollment, so engagements, notifications and webhooks fire as normal.
#!/usr/bin/env bash
# enroll.sh: enroll every email in emails.txt into course 42.
COURSE_ID=42
while read -r EMAIL; do
USER_ID=$(wp user get "$EMAIL" --field=ID 2>/dev/null)
if [ -z "$USER_ID" ]; then
echo "No account: $EMAIL"
continue
fi
wp eval "var_export( llms_enroll_student( $USER_ID, $COURSE_ID, 'llmsx_cli' ) );"
echo " $EMAIL"
done < emails.txt
llms_enroll_student() returns true on success and false if the student was already enrolled or enrollment failed. To create accounts first, use wp llms student create --email=person@example.com --porcelain or WordPress's wp user create command.
Enrolling hundreds of people triggers hundreds of welcome emails if you have enrollment engagements. Decide whether that is what you want before running it. Run large batches during quiet hours.
The add-on and license commands use the LifterLMS Helper, which is also bundled in core since 10.1.
# Activate a license key on this site
wp llms license activate YOUR-LICENSE-KEY
# Which add-ons are installed, and which have updates?
wp llms addon list --fields=name,status,version,update
wp llms addon list --update=available
# Install and activate an add-on
wp llms addon install lifterlms-groups --activate
# Preview, then run, updates for every installed add-on
wp llms addon update --all --dry-run
wp llms addon update --all
Add-on slugs work with or without the lifterlms- prefix, so advanced-videos and lifterlms-advanced-videos both work. With WP-CLI's aliases or a simple loop over SSH, this gives you a quick update report for every client site.
Agencies get the most from the CLI by running the same read-only command on every site. WP-CLI aliases make this tidy. Define each site once in ~/.wp-cli/config.yml, then loop:
# ~/.wp-cli/config.yml
@client-a:
ssh: deploy@client-a.example.com/var/www/html
@client-b:
ssh: deploy@client-b.example.com/var/www/html
# Version and pending add-on updates for each site
for SITE in @client-a @client-b; do
echo "== $SITE"
wp $SITE llms version
wp $SITE llms addon list --update=available --fields=name,version,update_version
done
The same pattern works for monthly reports, such as enrollment counts for each client's main course. Keep these loops read-only; for changes, connect to one site at a time so a mistake cannot spread.
LifterLMS runs recurring payments, access expirations, webhook deliveries and other jobs through Action Scheduler, which it bundles. Action Scheduler has its own WP-CLI command. On busy sites we disable WP-Cron's page-load trigger and run the queue from a real system cron:
# Every minute from the server's crontab
wp cron event run --due-now
wp action-scheduler run --batch-size=25
You can limit a run to one hook with --hooks=, for example llms_access_plan_expiration, which is useful when debugging. Be very careful with llms_charge_recurring_payment: running it charges real cards. On a cloned site, read our guide to staging sites and recurring payments first.
wp db export before-change.sql takes seconds.--user. Changes then carry a real user ID and the permission checks match that role.list, then act on IDs.Not on LifterLMS 10.1 or later. It is bundled in core. You do need WP-CLI on the server.
No. WP-CLI runs on the server. Without shell access, use the REST API, or the WordPress Abilities API covered in our guide to LifterLMS and AI agents.
Yes. LifterLMS publishes guidance for agents and recommends --format=json, --fields and --porcelain for parseable output. Give agents staging access first and review what they run.
Not among the wp llms commands. Use the export tools in the LifterLMS admin, described in import, export and cloning courses.
On a staging site, run wp help llms, then try the read-only recipes: list courses, read one course's content and count its enrollments. Once you trust the output, script the task you currently do by hand.
If you manage several LifterLMS sites and want scripted updates, bulk enrollment or a reliable cron setup, our LifterLMS support service handles it, and our development team can build custom commands for your workflows. Get in touch.
A practical reference to the LifterLMS hooks developers use most: enrollment, completion, quiz, order and registration actions, plus the filters that…
Read article
How LifterLMS finds template files, how to override one in a child theme, when a hook is the better choice, and a repeatable way to spot and update…
Read article
How LifterLMS detects a staging copy and pauses recurring payments, what the site URL lock is, the wp-config constants that make staging safe by…
Read articleSkip the trial and error. Get specialist LifterLMS help and ship faster.