Axle Review developer reference

Hooks

Every default, limit and message has a filter, and every change fires an action.

axle_review_capabilityFilter
( string $capability, int $post_id )

Who may create and revoke links for a post, checked as a meta capability. Default edit_post. An empty value keeps the default

axle_review_inbox_capabilityFilter
( string $capability )

Who sees Dashboard > Notes and Tools > Review Links. Default edit_posts

axle_review_settings_capabilityFilter
( string $capability )

Who changes the settings and pauses links. Default manage_options

axle_review_gate_override_capabilityFilter
( string $capability )

Who may publish past the gate with a reason. Default edit_others_posts

axle_review_post_typesFilter
( string[] $types )

Post types with links, the gate and the Notes column. Default: types with Notes support. Unknown types are dropped

axle_review_expiry_choicesFilter
( array $choices )

Seconds => label for new links. Choices under a minute or over the maximum are dropped

axle_review_default_expiryFilter
( int $seconds )

Default 7 days (the setting). Clamped to the maximum

axle_review_max_expiryFilter
( int $seconds )

Default 30 days, at least one hour

axle_review_default_max_viewsFilter
( int $views )

Default 0 (unlimited), from the setting

axle_review_code_lengthFilter
( int $digits )

Default 6, 4 to 10

axle_review_code_ttlFilter
( int $seconds )

Default 600, 60 to 3600

axle_review_code_max_triesFilter
( int $tries )

Wrong codes or passwords before a 15-minute lockout. Default 5, 1 to 20

axle_review_session_ttlFilter
( int $seconds )

Default 12 hours, 5 minutes to 30 days. The link’s expiry still ends it

axle_review_note_max_lengthFilter
( int $characters )

Default 2000, 1 to 20000

axle_review_min_secondsFilter
( int $seconds )

Least time between the page loading and a note. Default 3, 0 to 60

axle_review_guest_sees_othersFilter
( bool $share, int $link_id )

Whether a reviewer sees other reviewers’ notes. Default: the link’s setting, off

axle_review_note_contentFilter
( string $text, array $args )

A reviewer’s note before it is saved. Tags are stripped again after

axle_review_anchorFilter
( array|null $resolved, WP_Comment $note, array $anchor, array $blocks )

Where a reviewer note goes: path, orphan. Null leaves it unattached

axle_review_note_id_shapeFilter
( string $shape )

scalar or array for a block with no notes yet. Default array on 7.1+, else scalar

axle_review_gate_enabledFilter
( bool $enabled, WP_Post $post )

Whether the gate applies to a post

axle_review_gate_counts_noteFilter
( bool $counts, WP_Comment $note, WP_Post $post )

Whether one open note holds publishing back

axle_review_gate_messageFilter
( string $message, int $count, WP_Post $post )

The error and notice text

axle_review_inbox_viewsFilter
( array $views )

Key => label. Unknown keys are ignored; remove a key to hide a view

axle_review_inbox_per_pageFilter
( int $per_page )

Default 20, 1 to 100

axle_review_notify_recipientsFilter
( int[] $user_ids, string $event, array $context )

guest_note or reply. Each user’s preference still applies

axle_review_digest_scheduleFilter
( int $hour )

Site-time hour of the daily digest. Default 8, 0 to 23. Read when the event is scheduled

axle_review_email_subjectFilter
( string $subject, string $event, array $context )

code, link, guest_note, reply, digest. Empty keeps the default

axle_review_email_messageFilter
( string $message, string $event, array $context )

Plain text body. Empty keeps the default

axle_review_slack_payloadFilter
( array $payload, string $event, array $context )

The JSON sent to Slack. An empty array sends nothing

axle_review_event_retention_daysFilter
( int $days )

Link activity kept. Default 90, at least 1

axle_review_anonymize_ipFilter
( bool $anonymize )

Default true: wp_privacy_anonymize_ip()

axle_review_review_headersFilter
( array $headers )

Headers on review pages. Cache-Control and X-Robots-Tag are always kept

axle_review_toolbar_stringsFilter
( array $strings )

Toolbar and popover text by key. Missing or empty keys keep the default

axle_review_denied_messageFilter
( string $message, string $reason )

unknown, expired, used, revoked, paused

axle_review_editor_poll_secondsFilter
( int $seconds )

How often an open editor checks for new reviewer notes. Default 20, 5 to 600

axle_review_erase_deletes_notesFilter
( bool $delete, string $email )

Whether the privacy eraser deletes a reviewer’s notes instead of anonymising them. Default false

axle_review_delete_guest_notes_on_uninstallFilter
( bool $delete )

Whether uninstalling deletes reviewer notes. Default false: they are core Notes

axle_review_code_sentAction
( array $link )

after an email code was sent

axle_review_code_failedAction
( array $link )

after a wrong or expired code

axle_review_access_deniedAction
( string $reason, array|null $link )

when a link was refused

axle_review_guest_note_createdAction
( WP_Comment $note, array $link )

after a reviewer note or reply was saved

axle_review_guest_note_attachedAction
( WP_Comment $note, array $attached )

after it went on its block: path, orphan

axle_review_guest_note_orphanedAction
( WP_Comment $note, array $anchor )

when its block was gone

axle_review_note_resolvedAction
( WP_Comment $note, int $user_id )

after a resolve from the inbox, an ability or WP-CLI

axle_review_note_reopenedAction
( WP_Comment $note, int $user_id )

after a reopen from the same places

axle_review_gate_blockedAction
( WP_Post $post, WP_Comment[] $notes, string $to )

when open notes held publishing back

axle_review_gate_overriddenAction
( WP_Post $post, int $user_id, string $reason, WP_Comment[] $notes )

after someone chose to publish anyway

axle_review_digest_sentAction
( int $user_id, array $items )

after a digest email

axle_review_slack_failedAction
( array|WP_Error $response, string $event )

when Slack refused a message

WP-CLI

wp axle-review link create <post> [--label=<label>] [--expires=7d] [--views=1] [--email=<email>] [--password[=<password>]] [--no-notes] [--send-to=<email>] [--porcelain]
wp axle-review link list [--post=<id>] [--status=active|used|expired|revoked] [--format=<format>]
wp axle-review link revoke <id>... [--post=<id>]
wp axle-review link activity <id> [--format=<format>]
wp axle-review link pause
wp axle-review link resume
wp axle-review notes list [--status=unresolved|resolved|all] [--post=<id>] [--mentions=<user>] [--guests] [--format=<format>]
wp axle-review notes show <id> [--format=json|yaml]
wp axle-review notes add <post> --text=<text> [--block=<path>] [--match=<text>] [--reply-to=<id>] --user=<user>
wp axle-review notes resolve <id>... --user=<user>
wp axle-review notes reopen <id>... --user=<user>
wp axle-review notes reattach <post>
wp axle-review gate check <post> [--format=<format>]   # exits 1 when the gate would hold the post back
wp axle-review digest send [--user=<user>] [--frequency=hourly|daily]
wp axle-review prune

Abilities

What AI agents can do through the WordPress Abilities API and MCP, with the same permissions as the screen.

axle-review/list-notes

Read-only. Notes with status (unresolved, resolved, all), post, post_type, mentions (user ID, 7.1+), guests, since, page, per_page

Who can run it: the inbox capability; rows filtered by edit_post

axle-review/get-note-thread

Read-only. id: the note, replies, the block it is on (name, path, text) and the resolve/reopen history

Who can run it: edit_post on its post

axle-review/add-note

post, text, and block (a path such as 2 or 2.0) or match (text the block contains), or reply_to. mentions (user IDs) writes core mention chips on 7.1+. The note is by the current user

Who can run it: edit_post

axle-review/resolve-note

Idempotent. id

Who can run it: edit_post on its post

axle-review/reopen-note

Idempotent. id

Who can run it: edit_post on its post

axle-review/get-publish-readiness

Read-only. post: open notes, and whether the gate would hold it back

Who can run it: edit_post

axle-review/list-review-links

Read-only. post, status

Who can run it: the inbox capability; rows filtered by the share capability

axle-review/create-review-link

post, label, expires, max_views, email, allow_notes. Returns the URL once

Who can run it: the share capability on the post

axle-review/revoke-review-link

Destructive, idempotent. id

Who can run it: the share capability on the link’s post

Built from REFERENCE.md for version 1.0.0.

More on hooks

Filters

Example: let reviewers see each other’s notes on every link, and keep links alive after publishing for a post-launch check.

add_filter( 'axle_review_guest_sees_others', '__return_true' );
add_filter( 'axle_review_kill_link_on_status', function ( $statuses ) {
	return array_diff( $statuses, array( 'publish' ) );
} );

JavaScript (wp.hooks)

Read when used, so scripts that load later can hook in.

HookTypeWhereUse
axleReview.expiryChoicesfiltereditor panel( { value, label }[] choices ). Read each time the form opens
axleReview.blockSelectorfilterreview page( string selector ). Which elements count as a block in note mode. Only elements the review render marked can match
axleReview.popoverFieldsfilterreview page( string[] fields, config ). From name, email, note. The note is always there; email is left out on email-locked links
axleReview.inboxColumnsfilterDashboard > Notes( string[] columns ). Columns to show. The note column always stays
axleReview.linkCreatedactioneditor panel( result ) with url, link, emailed
axleReview.noteSubmittedactionreview page( response, element ) after a note or reply was saved
axleReview.noteAttachedInEditoractioneditor( { id, clientId } ) after a reviewer note was put on its block in an open editor
wp.hooks.addFilter( 'axleReview.blockSelector', 'my-site', () => '[data-axr-name="core/paragraph"], [data-axr-name="core/image"]' );

More on abilities

On WordPress 6.9 and later Axle Review registers abilities in the axle-review category, for AI agents through the MCP adapter and anything else through /wp-abilities/v1/. Each is marked public. They check the same capabilities as the screens. No ability pauses links, changes settings or publishes past the gate.

REST routes

Under /wp-json/axle-review/v1/:

RouteFor
GET, POST /guest/notes, POST /guest/pingthe review page. Session cookie plus X-Axle-Review-Nonce
GET, POST /links?post=, DELETE /links/<id>, GET /links/<id>/activity, POST /links/revoke-allthe editor panel. The share capability
GET /notes/pending?post=, GET /gate?post=, POST /gate/overridethe editor. edit_post; the override also needs the override capability

More on WP-CLI

--expires takes 90m, 12h, 7d, 2w or seconds. A bare --password reads the password from STDIN.

Data

WhereContents
{prefix}axle_review_links tableOne row per link: post, token hash, label, creator, created, expires, view limit, views, email (for codes), password hash, notes allowed, sharing, revoked when and by whom, last opened
{prefix}axle_review_events tableLink activity: open, code_sent, code_ok, code_fail, password_fail, note, reply_seen, denied, with the time, anonymised IP, browser family and note ID. Kept 90 days
Comment meta on reviewer notes_axr_link_id, _axr_anchor (path, hash, block name, quote), _axr_pending_attach, _axr_email_verified, _axr_session (to find a reviewer’s own threads), _axr_orphaned
User metaaxle_review_notify (instant, hourly, daily, off), axle_review_inbox_seen, axle_review_digest_sent
Optionsaxle_review_settings, axle_review_paused, axle_review_slack (webhook), axle_review_slack_status, axle_review_cache_warning, axle_review_db_version; site option axle_review_network_paused
TransientsEmail codes, failure counters, page render IDs, gate overrides
Cronaxle_review_prune (daily), axle_review_digest_hourly, axle_review_digest_daily

Uninstalling drops both tables and deletes the options, user meta, comment meta, transients and cron events, on every site of a network. Reviewer notes stay, since they are core Notes now; axle_review_delete_guest_notes_on_uninstall deletes them.