Header Actions
Add buttons to the page header, next to Save / Reset, with the page-level header_actions key:
return [ 'title' => __('Orders', 'my-plugin'), 'header_actions' => [ ['id' => 'export', 'label' => __('Export JSON', 'my-plugin'), 'href' => $exportUrl, 'target' => '_blank'], ['id' => 'recalculate', 'label' => __('Recalculate', 'my-plugin'), 'variant' => 'primary', 'confirm' => __('Are you sure?', 'my-plugin'), 'access' => 'manage_options'], ], 'tabs' => [ /* … */ ],];add_filter('my-plugin/header_action/{pageId}/recalculate', function ($unhandled, array $values, WP_REST_Request $request) { return ['status' => 'success', 'message' => __('Recalculated.', 'my-plugin')];}, 10, 3);A button with href is a plain link. Any other button works like an action field button: it posts the in-flight form values to {prefix}/header_action/{pageId}/{id} and takes the same variant, destructive, confirm and response shape. Returned html opens in a modal, and $values is scoped to the user’s access the same way.
Access
Section titled “Access”access uses the field format and defaults to the page capability. Running a button counts as an edit, so a user needs its edit rule (which falls back to view). Buttons the user can’t run are never sent to the browser, and their route returns 403.