Skip to content
ClientPress
  • Pricing
  • Features
  • Demo
  • 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 REST API

ClientPress REST API

13 min read

The ClientPress REST API lets you read portal data and automate portal creation from external systems — WooCommerce, SureCart, Zapier, n8n, custom scripts, or any HTTP client.

Base URL: https://your-site.com/wp-json/cp/v1


Quick Reference #

  • GET /portals — App Password — List accessible portals
  • POST /portals — App Password (admin) — Create a portal
  • GET /portals/{id} — App Password — Get a single portal
  • GET /portals/{id}/tasks — App Password — Get task lists and tasks
  • GET /portals/{id}/files — App Password — Get file records
  • GET /portals/{id}/deliverables — App Password — Get deliverable records
  • GET /portals/{id}/activity — App Password — Get activity log
  • POST /portals/{id}/invite — App Password (admin) — Send a client invitation
  • POST /webhook — API Key — Inbound automation actions
  • GET /verify — API Key — Test API key connection

Authentication #

ClientPress supports two authentication schemes depending on the use case.

WordPress Application Passwords (REST API) #

Used for all /portals endpoints. Available on all WordPress 5.6+ installs with SSL enabled.

Creating an Application Password:

  1. In WordPress admin go to Users → Your Profile (or any user’s profile if you’re an admin).
  2. Scroll to Application Passwords.
  3. Enter a name (e.g. Zapier Integration) and click Add New Application Password.
  4. Copy the generated password — it will not be shown again.

Making authenticated requests — pass credentials using HTTP Basic Auth:

curl https://your-site.com/wp-json/cp/v1/portals \
  -u "admin:abcd efgh ijkl mnop qrst uvwx"
const credentials = btoa('admin:abcdefghijklmnopqrstuvwx');
fetch('https://your-site.com/wp-json/cp/v1/portals', {
  headers: { 'Authorization': `Basic ${credentials}` }
});

API Keys (Inbound Webhooks) #

Used for the /webhook and /verify endpoints. Generated from Portals → Integrations in WP admin. Pass the key in the X-CP-API-Key header — no WP user account required.

curl https://your-site.com/wp-json/cp/v1/verify \
  -H "X-CP-API-Key: your-api-key"

See docs/inbound-webhooks.md for full details.

Access Levels #

  • manage_options (admin) — All portals; all write endpoints
  • cp_manager (project manager) — Assigned portals only; read-only via REST
  • cp_client (client) — Assigned portals only; read-only via REST

Project managers are WP users with the cp_manager role, assigned to specific portals from the portal edit screen. They have the same read access as clients via the REST API.


Endpoints #

List Portals #

GET /cp/v1/portals

Returns all portals the authenticated user can access. Admins receive all portals; clients and project managers receive only their assigned portals.

Response 200 OK:

[
  {
    "id": 42,
    "title": "Acme Corp",
    "slug": "acme-corp",
    "url": "https://your-site.com/client-portal/acme-corp/",
    "status": "active",
    "accent_color": "#0073aa",
    "allow_uploads": true,
    "client_user_id": 7,
    "sub_client_ids": [8, 9],
    "manager_ids": [12],
    "template_id": 3,
    "template_applied": "2024-01-15 10:30:00",
    "created_at": "2024-01-10 09:00:00"
  }
]

Get Portal #

GET /cp/v1/portals/{id}

Returns a single portal by ID.

Path parameters:

  • id (integer) — Portal post ID

Response 200 OK: Same shape as a single item from List Portals.

Portal object field reference:

  • id (integer) — Portal post ID
  • title (string) — Portal name
  • slug (string) — URL slug
  • url (string) — Full portal URL
  • status (string) — active | pending | archived
  • accent_color (string | null) — Hex colour, or null if unset
  • allow_uploads (boolean) — Whether the client can upload files
  • client_user_id (integer | null) — Primary client WP user ID, or null
  • sub_client_ids (integer[]) — Additional client WP user IDs
  • manager_ids (integer[]) — Assigned project manager WP user IDs
  • template_id (integer | null) — Last applied portal template ID, or null
  • template_applied (string | null) — Datetime of last template application, or null
  • created_at (string) — Portal creation datetime (YYYY-MM-DD HH:MM:SS)

Error responses:

  • 403 Forbidden — Authenticated user does not have access to this portal
  • 404 Not Found — No portal exists with this ID

Get Tasks #

GET /cp/v1/portals/{id}/tasks

Returns all task lists and their tasks for the portal. Tasks include assignee user IDs.

Response 200 OK:

[
  {
    "id": 1,
    "name": "Onboarding",
    "sort_order": 0,
    "created_at": "2024-01-10 09:00:00",
    "tasks": [
      {
        "id": 10,
        "title": "Sign the contract",
        "description": "",
        "status": "complete",
        "due_date": "2024-01-20",
        "assignee_ids": [7],
        "sort_order": 0,
        "created_at": "2024-01-10 09:00:00",
        "updated_at": "2024-01-18 14:22:00"
      },
      {
        "id": 11,
        "title": "Schedule kickoff call",
        "description": "Use the Calendly link in your welcome email.",
        "status": "open",
        "due_date": null,
        "assignee_ids": [],
        "sort_order": 1,
        "created_at": "2024-01-10 09:00:00",
        "updated_at": "2024-01-10 09:00:00"
      }
    ]
  }
]

Field reference:

  • status (string) — open | up_next | in_progress | complete
  • due_date (string | null) — YYYY-MM-DD or null
  • assignee_ids (integer[]) — WP user IDs

Get Files #

GET /cp/v1/portals/{id}/files

Returns file records for the portal. Visibility matches the portal UI: pending and rejected files are only visible to the uploader, designated approver, and admins.

Response 200 OK:

[
  {
    "name": "contract-q1-2024.pdf",
    "original": "Contract Q1 2024.pdf",
    "size": 204800,
    "type": "application/pdf",
    "url": "https://your-site.com/cp-file/42/contract-q1-2024.pdf",
    "uploaded_by": 1,
    "uploaded_at": "2024-01-10 09:00:00",
    "approval_status": "approved",
    "approver_id": null,
    "rejection_note": null,
    "approved_at": "2024-01-11 10:15:00"
  }
]

Field reference:

  • name (string) — Internal filename (URL-safe)
  • original (string) — Display name shown in the portal
  • size (integer) — File size in bytes (0 for linked files)
  • type (string) — MIME type (empty string for linked files)
  • url (string) — Authenticated serving URL (see note below)
  • uploaded_by (integer) — WP user ID of the uploader
  • uploaded_at (string) — Upload datetime
  • approval_status (string) — none | pending | approved | rejected
  • approver_id (integer | null) — WP user ID of the designated approver, or null
  • rejection_note (string | null) — Rejection message from the approver, or null
  • approved_at (string | null) — Approval/rejection datetime, or null

File URLs point to the authenticated serving endpoint (/cp-file/{portal_id}/{filename}). A logged-in portal member session is required — these URLs are not publicly accessible.


Get Deliverables #

GET /cp/v1/portals/{id}/deliverables

Returns all deliverable records for the portal. Available to all portal members (clients, project managers, admins).

Response 200 OK:

[
  {
    "id": "del_6831fa2b4c8e1",
    "original": "Homepage Design v1",
    "url": "https://your-site.com/cp-deliverable/42/homepage-design-v1.pdf",
    "linked": false,
    "size": 512000,
    "type": "application/pdf",
    "category": "web-pages",
    "uploaded_by": 1,
    "uploaded_at": "2025-06-01 10:00:00",
    "status": "approved",
    "revisions_allowed": 3,
    "revisions_used": 1,
    "revision_note": "",
    "version_count": 2,
    "approved_by": 7,
    "approved_at": "2025-06-03 14:30:00"
  }
]

Field reference:

  • id (string) — Stable unique ID for this deliverable (persists across version uploads)
  • original (string) — Display name shown in the portal
  • url (string) — Authenticated serving URL for file deliverables; external URL for linked deliverables
  • linked (boolean) — true if this is an external URL rather than an uploaded file
  • size (integer) — File size in bytes; 0 for linked deliverables
  • type (string) — MIME type; empty string for linked deliverables
  • category (string) — Category slug from Settings → Deliverables → Categories; empty string if uncategorised
  • uploaded_by (integer) — WP user ID of the uploader
  • uploaded_at (string) — Upload datetime of the current version
  • status (string) — pending | in_review | revision_requested | approved
  • revisions_allowed (integer) — Total revision rounds permitted (from category or global setting)
  • revisions_used (integer) — Revision rounds consumed so far
  • revision_note (string) — Client’s note from the most recent revision request; empty string if none
  • version_count (integer) — Total versions uploaded (current + archived history)
  • approved_by (integer | null) — WP user ID of the approver, or null
  • approved_at (string | null) — Approval datetime, or null

Interpreting approved_by: null on an approved deliverable: When a deliverable is uploaded with the “Require client approval” toggle unchecked, its status is immediately approved but approved_by and approved_at are both null — no approval action was taken. This is distinct from a client-approved deliverable, which has a non-null approved_by.

Deliverable statuses:

  • pending — Uploaded but not yet sent to the client for review
  • in_review — Marked ready — client can approve or request revisions
  • revision_requested — Client has requested changes; admin/PM should upload a new version
  • approved — Client has approved the deliverable

File URLs point to /cp-deliverable/{portal_id}/{filename} — a logged-in portal member session is required. The full revision_history array is not included in the REST response; use the portal UI to view the version history accordion.


Get Activity #

GET /cp/v1/portals/{id}/activity

Returns the activity log for the portal in reverse-chronological order.

Query parameters:

  • limit (integer, default 25, max 100) — Number of events to return
  • offset (integer, default 0) — Offset for pagination

Response 200 OK:

{
  "total": 47,
  "limit": 25,
  "offset": 0,
  "items": [
    {
      "id": 123,
      "user_id": 1,
      "action": "task_completed",
      "object_label": "Sign the contract",
      "description": "Admin completed <strong>Sign the contract</strong>",
      "created_at": "2024-01-18 14:22:00"
    },
    {
      "id": 122,
      "user_id": 7,
      "action": "message_sent",
      "object_label": "",
      "description": "Jane Smith sent a message",
      "created_at": "2024-01-17 11:05:00"
    }
  ]
}

action values:

  • portal_created — Portal created via REST API
  • file_uploaded — File uploaded
  • file_linked — External URL added as a file entry
  • file_deleted — File deleted
  • file_approval_requested — File uploaded with approval required
  • file_approved — File approved
  • file_rejected — File rejected
  • deliverable_uploaded — Deliverable uploaded
  • deliverable_linked — External URL added as a deliverable
  • deliverable_deleted — Deliverable deleted
  • deliverable_in_review — Deliverable marked ready for client review
  • deliverable_approved — Deliverable approved by client
  • deliverable_revision_requested — Client requested a revision
  • task_created — Task added
  • task_completed — Task marked complete
  • task_reopened — Task reopened
  • task_deleted — Task deleted
  • message_sent — Discussion message sent
  • board_topic_posted — Board topic created
  • board_reply_posted — Board reply posted
  • client_invited — Invitation email sent

Pagination example — fetch events 26–50:

GET /cp/v1/portals/42/activity?limit=25&offset=25

Create Portal #

POST /cp/v1/portals

Creates a new published portal. Optionally assigns a client user and applies a portal template in the same request.

Requires: manage_options (admin)

Request body (JSON):

  • title (string, required) — Portal name
  • status (string, default active) — active | pending | archived
  • accent_color (string, default "") — Hex colour, e.g. #ff6600. Empty leaves accent unset.
  • allow_uploads (boolean, default true) — Whether the client can upload files
  • client_user_id (integer, default 0) — WP user ID to assign as primary client. 0 = unassigned.
  • template_id (integer, default 0) — Portal template ID to apply. 0 = no template.

Example:

curl -X POST https://your-site.com/wp-json/cp/v1/portals \
  -u "admin:your-app-password" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Riverside Dental",
    "status": "pending",
    "accent_color": "#2d6a4f",
    "allow_uploads": true,
    "template_id": 3
  }'

Response 201 Created: Portal object (see field reference above).

{
  "id": 58,
  "title": "Riverside Dental",
  "slug": "riverside-dental",
  "url": "https://your-site.com/client-portal/riverside-dental/",
  "status": "pending",
  "accent_color": "#2d6a4f",
  "allow_uploads": true,
  "client_user_id": null,
  "sub_client_ids": [],
  "manager_ids": [],
  "template_id": 3,
  "template_applied": "2024-02-01 09:15:22",
  "created_at": "2024-02-01 09:15:22"
}

Notes:

  • If template_id is provided, the template is applied synchronously before the response is returned — task lists, tools, and the welcome message are populated immediately.
  • If client_user_id is provided, the user must already exist in WordPress. To create a new client account, use the invite endpoint after creating the portal.
  • The portal slug is auto-generated from the title by WordPress.

Send Invitation #

POST /cp/v1/portals/{id}/invite

Sends a client invitation email. The client receives a one-time link to set their password and activate their account. On acceptance, a cp_client role WP user is created and assigned to the portal.

Requires: manage_options (admin)

Request body (JSON):

  • email (string, required) — Recipient email address
  • name (string) — Client’s display name, included in the greeting

Example:

curl -X POST https://your-site.com/wp-json/cp/v1/portals/58/invite \
  -u "admin:your-app-password" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@riverside-dental.com",
    "name": "Jane Smith"
  }'

Response 200 OK:

{
  "message": "Invitation sent to jane@riverside-dental.com.",
  "email": "jane@riverside-dental.com"
}

Error responses:

  • 400 invalid_portal — Portal ID does not exist
  • 400 portal_not_published — Portal is a draft — publish it first
  • 400 invalid_email — Email address is not valid
  • 409 user_exists — A WP account already exists for this email
  • 429 rate_limited — More than 20 invitations sent within the last hour
  • 500 mail_failed — WordPress could not send the email

Inbound Webhook #

POST /cp/v1/webhook

Accepts action-based payloads from external automation tools (Zapier, Make, n8n, OttoKit, custom scripts). Authenticated via X-CP-API-Key header — no WP user account required.

Supported actions:

  • create_portal — Create a portal with optional status, accent, client assignment, and template
  • send_invite — Send a client invitation email for a specific portal
  • assign_user — Assign an existing WP user to a portal by email address
  • update_portal — Update a portal’s status, accent colour, or upload permission

All actions accept and return JSON. See docs/inbound-webhooks.md for the full payload reference, field descriptions, and example requests for each action.

Example — create a portal and send an invite in one webhook call:

# Step 1: create the portal
curl -X POST https://your-site.com/wp-json/cp/v1/webhook \
  -H "X-CP-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"action":"create_portal","title":"Sunset Bakery","status":"pending","template_id":3}'

# Step 2: send the invite
curl -X POST https://your-site.com/wp-json/cp/v1/webhook \
  -H "X-CP-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"action":"send_invite","portal_id":58,"email":"owner@sunsetbakery.com","name":"Maria"}'

Verify Connection #

GET /cp/v1/verify

Lightweight endpoint for testing an API key and confirming the plugin is reachable. Used by OttoKit and other integrations during initial setup.

Requires: X-CP-API-Key header

Response 200 OK:

{
  "success": true,
  "site": "https://your-site.com",
  "version": "1.2.0"
}

Automation Examples #

Create a portal, apply a template, and invite the client #

PORTAL=$(curl -s -X POST https://your-site.com/wp-json/cp/v1/portals \
  -u "admin:your-app-password" \
  -H "Content-Type: application/json" \
  -d '{"title":"Acme Corp","status":"pending","template_id":3}')

PORTAL_ID=$(echo $PORTAL | jq '.id')

curl -X POST https://your-site.com/wp-json/cp/v1/portals/$PORTAL_ID/invite \
  -u "admin:your-app-password" \
  -H "Content-Type: application/json" \
  -d '{"email":"client@acme.com","name":"John Doe"}'

Poll for approved deliverables (e.g. from a cron job) #

curl https://your-site.com/wp-json/cp/v1/portals/42/deliverables \
  -u "admin:your-app-password" \
  | jq '[.[] | select(.status == "approved")]'

Check for revision requests since yesterday (via activity log) #

curl "https://your-site.com/wp-json/cp/v1/portals/42/activity?limit=50" \
  -u "admin:your-app-password" \
  | jq '[.items[] | select(.action == "deliverable_revision_requested")]'

Error Format #

All errors follow the standard WordPress REST API format:

{
  "code": "rest_forbidden",
  "message": "You do not have access to this portal.",
  "data": { "status": 403 }
}

Not Yet Available via REST #

The following operations remain AJAX-only in the current version and will be added in a future release:

  • Create / update / delete tasks and task lists
  • Upload or delete files
  • Upload, approve, or request revisions on deliverables
  • Post discussion messages
  • Post board topics and replies
  • Assign project managers to portals
  • Manage portal template definitions

PortalTemplates::apply_to_portal() is already callable directly from PHP for headless or plugin-to-plugin use cases without waiting for the REST endpoint.

Updated on June 9, 2026

What are your Feelings

  • Happy
  • Normal
  • Sad

Share This Article :

  • Facebook
  • X
  • LinkedIn
  • Pinterest
ClientPress Inbound WebhooksClientPress Abilities API Integration

Leave a ReplyCancel reply

Table of Contents
  • Quick Reference
  • Authentication
    • WordPress Application Passwords (REST API)
    • API Keys (Inbound Webhooks)
    • Access Levels
  • Endpoints
    • List Portals
    • Get Portal
    • Get Tasks
    • Get Files
    • Get Deliverables
    • Get Activity
    • Create Portal
    • Send Invitation
    • Inbound Webhook
    • Verify Connection
  • Automation Examples
    • Create a portal, apply a template, and invite the client
    • Poll for approved deliverables (e.g. from a cron job)
    • Check for revision requests since yesterday (via activity log)
  • Error Format
  • Not Yet Available via REST

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
  • Demo
  • Use Cases
    • Coaches and Consultants
    • Employee Onboarding
    • Freelancers and Contractors
    • Teams Working With Outside Freelancers
    • Web and Digital Agencies
  • Contact
  • Log In
  • 0

Notifications