Skip to content
ClientPress
  • Pricing
  • Features
  • Use CasesExpand
    • Coaches and Consultants
    • Employee Onboarding
    • Freelancers and Contractors
    • Teams Working With Outside Freelancers
    • Web and Digital Agencies
  • Contact
  • Log In
  • 0
ClientPress

Getting Started

7
  • Inviting a Client to Their Portal
  • Creating Your First Portal
  • User Roles Explained
  • Initial Setup Checklist
  • Plugin Overview — What ClientPress Does
  • Magic Login Links in Email Notifications
  • How to Link Clients to Their Portal

Navigation

1
  • How Client Login and Redirect Works

Assets, Files, and Deliverables

1
  • Portal Files — Browsing All Uploaded Files Across Portals

Client Setup

4
  • Onboarding — Guiding Clients Through Their First Steps
  • Managing Client Invitations
  • Assigning Project Managers to a Portal
  • Adding Sub-Clients to a Portal

Advanced

3
  • Uninstalling ClientPress — What Data Gets Deleted
  • Private File Storage and Security
  • Activity Log — What Gets Tracked and How to Use It

Automations and Integrations

5
  • REST API Overview
  • Connecting ClientPress to OttoKit
  • Connecting ClientPress to Make
  • Connecting ClientPress to Zapier
  • Using Webhooks with ClientPress

Features and Tabs

14
  • Onboarding — Guiding Clients Through Their First Steps
  • Docs — Adding Portal-Specific Client Documents
  • Guides — Creating and Assigning Global Support Docs
  • People Tab — Managing Portal Members
  • Tools & Links Tab — Building a Client Resource Board
  • Managing Deliverable Revisions
  • Deliverables — Sending Work for Client Approval
  • File Approval Workflow
  • Files Tab — Uploading and Managing Client Files
  • Calendar View — Visualizing Task Due Dates
  • Using the Kanban Board View for Tasks
  • Task Manager — Creating and Managing Tasks
  • Message Board — Topic-Based Team Discussions
  • Discussion Tab — Private Messaging with Clients

Notifications and Emails

3
  • Enabling or Disabling Admin Notifications
  • How Clients Can Manage Their Notification Preferences
  • How Portal Notifications Work

Portals and Hubs

6
  • Setting Portal Width and Layout per View
  • Configuring the Portal Landing Tab
  • Branding a Portal
  • Using Portal Templates
  • Managing Portal Status
  • Understanding Portals and Hubs (Child Portals)

Settings and Configuration

5
  • Setting Up the Login Redirect
  • Appearance Settings
  • Configuring Deliverable Categories and Revision Limits
  • Configuring File Upload Settings
  • Enabling and Disabling Portal Features Globally

Shortcodes and Theme

2
  • Customizing Portal Colors with the Theme Customizer
  • Shortcode Reference

Developer

5
  • ClientPress Hooks & Filters
  • ClientPress Outbound Webhooks
  • ClientPress Inbound Webhooks
  • ClientPress REST API
  • ClientPress Abilities API Integration
View Categories
  • Home
  • Support Documentation
  • Developer
  • ClientPress Abilities API Integration

ClientPress Abilities API Integration

9 min read

WordPress 7.0 introduced the Abilities API — a structured registry that lets plugins declare what they can do so that AI agents, browser extensions, and WebMCP integrations can discover and execute those actions programmatically.

ClientPress implements this API. This document explains the architecture, lists every registered ability, describes what end users can do with it today, and lays out how to extend it in the future.


How It Works #

The two-package model #

WordPress ships two JavaScript packages:

  • @wordpress/abilities — Pure state management. Provides the store, registerAbility, executeAbility, etc. No WordPress server dependency.
  • @wordpress/core-abilities — WordPress integration layer. When loaded, auto-fetches all server-registered abilities via /wp-abilities/v1/ and registers them in the store. Core enqueues this on every admin page.

Because WordPress core enqueues @wordpress/core-abilities on all admin pages, every ability ClientPress registers on the PHP side is automatically available to any AI agent or browser extension that queries the abilities store — no additional client-side setup required.

How server-side abilities work #

  1. ClientPress calls wp_register_ability_category() and wp_register_ability() on the init hook.
  2. WordPress exposes these over the REST endpoint /wp-abilities/v1/.
  3. Any client that loads @wordpress/core-abilities fetches that endpoint and hydrates the store.
  4. When a client calls executeAbility('clientpress/create-portal', { title: 'Acme' }), WordPress routes it back to the server via the REST API and calls our PHP callback.
  5. Our callback runs, creates the portal, fires the activity log and webhook, and returns a typed output.

How client-side abilities work #

ClientPress also enqueues assets/js/cp-abilities.js as an ES module on every admin page. This module imports from @wordpress/abilities and registers navigation abilities that only exist in the browser — no server round-trip needed.

Backward compatibility #

Both the PHP ability registration and the JS module enqueue are guarded:

// PHP side
if ( ! function_exists( 'wp_register_ability_category' ) ) {
    return;
}

// JS side
if ( ! function_exists( 'wp_enqueue_script_module' ) ) {
    return;
}

On WordPress versions before 7.0, the entire feature silently no-ops. No errors, no broken admin pages.


Registered Abilities #

All server-side abilities require the executing user to have manage_options. Validation against input_schema and output_schema is handled automatically by WordPress before and after the callback runs.

Category: clientpress-portals #

clientpress/create-portal #

Creates a new client portal.

  • title (string, required) — Portal title
  • status (active | pending | archived) — Defaults to active
  • accent_color (string) — Hex colour, e.g. #3b82f6
  • allow_uploads (boolean) — Defaults to true
  • client_user_id (integer) — WP user ID of the primary client
  • template_id (integer) — Portal template ID to apply on creation

Output: { id, title, url }

Fires: ActivityLog::PORTAL_CREATED, portal.created webhook.


clientpress/update-portal #

Updates an existing portal’s settings.

  • portal_id (integer, required) — Portal post ID
  • status (active | pending | archived)
  • accent_color (string) — Hex colour
  • allow_uploads (boolean)

Output: { id, success }


clientpress/invite-client #

Sends a client invitation email and creates a time-limited signup link.

  • portal_id (integer, required) — Portal post ID
  • email (string/email, required) — Client email address
  • name (string) — Client display name

Output: { success, message }

Delegates to Invitations::send_invite() — identical to sending an invite from the portal editor UI.


clientpress/assign-client #

Assigns an existing WordPress user to a portal. If no primary client is set, the user becomes primary; otherwise they are added as a sub-client.

  • portal_id (integer, required) — Portal post ID
  • user_id (integer, required) — WP user ID to assign

Output: { portal_id, role } where role is primary or sub-client.


clientpress/create-hub #

Creates a child portal (hub) nested under a parent portal.

  • title (string, required) — Hub title
  • parent_portal_id (integer, required) — Parent portal post ID
  • status (active | pending | archived) — Defaults to active

Output: { id, title, url }


Category: clientpress-tasks #

Only registered when Settings → Task Manager is enabled.

clientpress/create-task #

Creates a new task in a portal task list.

  • portal_id (integer, required) — Portal post ID
  • list_id (integer, required) — Task list ID
  • title (string, required) — Task title
  • assignee_ids (integer[]) — WP user IDs to assign

Output: { id, title }

Fires: ActivityLog::TASK_CREATED, task.created webhook, task assignment notification emails.


clientpress/update-task-status #

Changes the status of a task.

  • task_id (integer, required) — Task ID
  • status (open | up_next | in_progress | complete, required) — New status

Output: { task_id, status }

Fires: TASK_COMPLETED, TASK_REOPENED, or TASK_STATUS_CHANGED depending on the new status. Fires task.completed webhook when status is complete.


Category: clientpress-files #

clientpress/approve-file #

Approves a pending file upload.

  • portal_id (integer, required) — Portal post ID
  • filename (string, required) — Internal filename key (from the _cp_files record’s name field)

Output: { success, approved_at }

Fires: ActivityLog::FILE_APPROVED, approval notification email to uploader, file.approved webhook.


clientpress/reject-file #

Rejects a pending file upload.

  • portal_id (integer, required) — Portal post ID
  • filename (string, required) — Internal filename key
  • note (string) — Rejection reason shown to the uploader

Output: { success, rejected_at }

Fires: ActivityLog::FILE_REJECTED, rejection notification email to uploader, file.rejected webhook.


Category: clientpress-navigate (client-side only) #

These abilities are registered in JavaScript and only perform in-browser navigation. They appear in the WordPress command palette and are available to browser agents. They do not make server round-trips.

  • clientpress/navigate-to-portal — Opens a portal’s edit screen. Input: { portal_id }
  • clientpress/navigate-to-settings — Opens the ClientPress settings page
  • clientpress/navigate-to-invitations — Opens the invitations management page

All navigation abilities carry meta.annotations.readonly: true so WordPress routes execution as GET.


What Users Can Do With This Today #

Once on WordPress 7.0, any AI agent or automation tool that understands the Abilities API can interact with ClientPress without custom integration code. Practical examples:

Onboard a new client in one step

“Create a portal for Acme Corp, apply the Standard Onboarding template, and send an invite to jane@acme.com.”

The agent calls clientpress/create-portal with the template, then clientpress/invite-client — two ability calls, no clicking.

Automate project kickoff

“When a new deal is marked Won in my CRM, create a portal, create a ‘Project Kickoff’ task list with three tasks, and assign them to my team.”

A workflow tool can chain clientpress/create-portal → clientpress/create-task × 3 using data from the CRM trigger.

Archive completed engagements

“Set all portals tagged ‘Q1 2026’ to Archived.”

The agent queries portals via GET /cp/v1/portals, then calls clientpress/update-portal for each one.

Command palette shortcuts Admins can type “Navigate to portal” or “Go to Invitations” in the WordPress command palette and jump directly — no mouse required.

Browser agent automation Browser extensions built on WebMCP can list available ClientPress abilities, prompt the user to confirm, and execute them — all through the standard Abilities API interface.


Architecture Notes #

Audit trail parity #

Every server-side ability callback fires the same activity log entries, notification emails, and outbound webhooks as the equivalent AJAX or REST API action. An AI agent creating a portal is indistinguishable from an admin doing it manually in the audit trail. This is intentional — it means existing monitoring and webhook consumers work without changes.

Abilities vs the existing REST API #

The REST API (cp/v1) and the Abilities API serve different purposes and are both kept:

  • REST API (cp/v1) — Primary consumer: OttoKit, Zapier, n8n, custom code. Auth: Application Passwords or API key. Discovery: manual (docs). Schema validation: per-endpoint args. Navigation: not applicable.
  • Abilities API — Primary consumer: AI agents, browser extensions, WP command palette. Auth: WordPress session (same user doing the action). Discovery: automatic via /wp-abilities/v1/. Schema validation: JSON Schema draft-04, automatic. Navigation: supported (client-side abilities).

Why callbacks don’t call the REST handlers #

The REST handlers (RestAPI::create_portal(), etc.) accept \WP_REST_Request objects and return \WP_REST_Response. Ability callbacks accept plain arrays and return plain arrays or \WP_Error. Rather than wrapping one format in the other, the callbacks call the same underlying WordPress and ClientPress functions directly (wp_insert_post, update_post_meta, Invitations::send_invite, Tasks::create, etc.). If shared logic grows complex enough to warrant extraction, a PortalService or similar class would be the right place to put it.


Extending in the Future #

Adding a new ability #

  1. Register a new wp_register_ability() call in Abilities::register_server_abilities().
  2. Add a static callback method on the Abilities class.
  3. Define input_schema and output_schema using JSON Schema draft-04.
  4. Call any necessary activity log, webhook, and notification methods from the callback — same as you would in a REST handler or AJAX handler.

Example skeleton:

wp_register_ability( [
    'name'                => 'clientpress/archive-portal',
    'label'               => __( 'Archive Portal', 'clientpress' ),
    'description'         => __( 'Moves a portal to Archived status', 'clientpress' ),
    'category'            => 'clientpress-portals',
    'permission_callback' => fn() => current_user_can( 'manage_options' ),
    'meta'                => [ 'annotations' => [ 'destructive' => true, 'idempotent' => true ] ],
    'input_schema'        => [
        'type'       => 'object',
        'properties' => [
            'portal_id' => [ 'type' => 'integer' ],
        ],
        'required' => [ 'portal_id' ],
    ],
    'output_schema' => [
        'type'       => 'object',
        'properties' => [
            'success' => [ 'type' => 'boolean' ],
        ],
        'required' => [ 'success' ],
    ],
    'callback' => [ self::class, 'cb_archive_portal' ],
] );

Abilities worth adding next #

  • clientpress/get-portal-activity — Read-only; useful for agents that summarise what happened in a portal. Annotate readonly: true.
  • clientpress/create-task-list — Agents can’t currently create a list to put tasks in — they can only add to existing ones.
  • clientpress/delete-portal — Destructive; annotate destructive: true. Gate carefully.
  • clientpress/search-portals — Lets agents find a portal by name before acting on it. Annotate readonly: true.
  • clientpress/get-pending-files — Let agents surface a summary of files awaiting approval across all portals.

Adding client-side abilities #

Client-side abilities go in assets/js/cp-abilities.js. Import from @wordpress/abilities and call registerAbility. These are good for:

  • Navigation shortcuts (already done)
  • UI state changes that don’t need a server round-trip
  • Triggering existing portal JavaScript actions (e.g. opening the invite modal)

Allowing clients (not just admins) to use abilities #

Currently all server-side abilities require manage_options. If a future version wants to expose abilities to portal clients — e.g. clientpress/upload-file or clientpress/post-message — the permission_callback should use PostTypes::current_user_can_view( $portal_id ) instead. Be deliberate about which actions clients should be able to trigger from an AI agent vs. only from the portal UI.

Exposing abilities conditionally by feature flag #

The task abilities already demonstrate this pattern — they only register when tasks_enabled is on. Apply the same pattern to any future ability that depends on a feature toggle:

if ( Admin\Settings::get()['discussions_enabled'] ) {
    wp_register_ability( [ 'name' => 'clientpress/post-message', ... ] );
}
Updated on June 9, 2026

What are your Feelings

  • Happy
  • Normal
  • Sad

Share This Article :

  • Facebook
  • X
  • LinkedIn
  • Pinterest
ClientPress REST APIClientPress Hooks & Filters

Leave a ReplyCancel reply

Table of Contents
  • How It Works
    • The two-package model
    • How server-side abilities work
    • How client-side abilities work
    • Backward compatibility
  • Registered Abilities
    • Category: clientpress-portals
      • clientpress/create-portal
      • clientpress/update-portal
      • clientpress/invite-client
      • clientpress/assign-client
      • clientpress/create-hub
    • Category: clientpress-tasks
      • clientpress/create-task
      • clientpress/update-task-status
    • Category: clientpress-files
      • clientpress/approve-file
      • clientpress/reject-file
    • Category: clientpress-navigate (client-side only)
  • What Users Can Do With This Today
  • Architecture Notes
    • Audit trail parity
    • Abilities vs the existing REST API
    • Why callbacks don’t call the REST handlers
  • Extending in the Future
    • Adding a new ability
    • Abilities worth adding next
    • Adding client-side abilities
    • Allowing clients (not just admins) to use abilities
    • Exposing abilities conditionally by feature flag

Use Cases

  • Coaches and Consultants
  • Employee Onboarding
  • Freelancers and Independent Contractors
  • Teams Working With Outside Freelancers
  • Web and Digital Agencies

How We Compare

  • Market Comparison
  • ClientPress vs Client Portal
  • ClientPress vs. Asana
  • ClientPress vs. Basecamp
  • ClientPress vs. Microsft Teams
  • Clientpress vs. Clickup

Customers

  • Dashboard

Support

  • Documentation
  • Support
  • Changelog
  • Roadmap

Affiliates

  • Affiliate Program
  • Affiliate Dashboard
  • Affiliate Terms and Conditions

Legal

  • Privacy Policy
  • Terms of Service

© 2026 ClientPress

Review My Order

0

Subtotal

Taxes & shipping calculated at checkout

Checkout
  • Pricing
  • Features
  • Use Cases
    • Coaches and Consultants
    • Employee Onboarding
    • Freelancers and Contractors
    • Teams Working With Outside Freelancers
    • Web and Digital Agencies
  • Contact
  • Log In
  • 0

Notifications