NimblyMail exposes a single action hook that fires during rest_api_init after all core controllers are registered. A Pro add-on hooks here to register its own controllers using standard WordPress REST APIs. The free plugin places no constraints on the Pro namespace, route structure, or authentication scheme.
Registering a Pro REST Controller
Step 1 — Extend AbstractController
NimblyMailRestAbstractController enforces the manage_options capability check and provides a send_error() helper. Extending it is optional but recommended for consistency.
<?php
defined( 'ABSPATH' ) || exit;
use NimblyMailRestAbstractController;
use WP_REST_Request;
use WP_REST_Response;
/**
* REST controller for Pro reporting endpoints.
*
* @since 1.0.0 Added Pro reporting endpoints.
*/
class NimblyMail_Pro_Reports_Controller extends AbstractController {
/**
* Register all routes for this controller.
*
* @since 1.0.0 Added Pro reporting endpoints.
*
* @return void
*/
public function register_routes(): void {
register_rest_route(
'nimbly-mail-pro/v1',
'/reports/generate',
array(
'methods' => 'POST',
'callback' => array( $this, 'generate_report' ),
'permission_callback' => array( $this, 'permissions_check' ),
'args' => array(
'date_from' => array(
'type' => 'string',
'format' => 'date',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'date_to' => array(
'type' => 'string',
'format' => 'date',
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
),
)
);
register_rest_route(
'nimbly-mail-pro/v1',
'/reports/bounce-rate',
array(
'methods' => 'GET',
'callback' => array( $this, 'get_bounce_rate' ),
'permission_callback' => array( $this, 'permissions_check' ),
)
);
}
/**
* Generate a delivery report for the requested date range.
*
* @since 1.0.0 Added Pro reporting endpoints.
*
* @param WP_REST_Request $request The REST request object.
*
* @return WP_REST_Response The report data.
*/
public function generate_report( WP_REST_Request $request ): WP_REST_Response {
$from = $request->get_param( 'date_from' );
$to = $request->get_param( 'date_to' );
// ... build report ...
$report = array( 'rows' => array() );
return new WP_REST_Response( $report, 200 );
}
/**
* Return the 24-hour bounce rate stat.
*
* @since 1.0.0 Added Pro reporting endpoints.
*
* @param WP_REST_Request $request The REST request object.
*
* @return WP_REST_Response The bounce rate data.
*/
public function get_bounce_rate( WP_REST_Request $request ): WP_REST_Response {
return new WP_REST_Response(
array(
'value' => 1.4,
'unit' => '%',
'trend' => 'down',
),
200
);
}
}
Step 2 — Register via the action hook
Signature: do_action( 'nimbly_mail_register_rest_routes' )
Fires during rest_api_init immediately after NimblyMail’s own controllers are registered. No parameters are passed; use register_rest_route() directly.
@since 1.0.0
add_action(
'nimbly_mail_register_rest_routes',
function (): void {
$controller = new NimblyMail_Pro_Reports_Controller();
$controller->register_routes();
}
);
Namespace Recommendation
Use your own namespace — nimbly-mail-pro/v1 is the recommended convention. Registering routes under nimbly-mail/v1 is not blocked by the free plugin, but doing so creates a maintenance hazard: a future NimblyMail update could register a conflicting route under the same path.
Permission Callback Warning
Every route MUST set a
permission_callback. Using__return_trueas the permission callback is a security vulnerability — it exposes the endpoint to unauthenticated requests from anywhere on the internet.
AbstractController::permissions_check() already enforces current_user_can( 'manage_options' ) and returns the appropriate WP_Error for unauthorized requests. Inherit it by passing array( $this, 'permissions_check' ) as shown above.
If your endpoint is intentionally public (for example, a webhook receiver), implement an explicit token-based or signature-based check in the permission_callback — do not use __return_true.
