Last updated: March 16, 2026

To set up a ClickUp client portal, create a dedicated space with guest access configured to specific lists, then use ClickUp’s API to automate guest provisioning and filter client-facing views. This approach gives remote development teams visibility into project progress while keeping internal technical discussions private.

Guest Access vs. Client Portal: Understanding Your Options

ClickUp offers two primary mechanisms for external client visibility:

  1. Guest Access — Invite clients as guests to specific spaces, folders, or lists. Guests receive credentials but can only see what you explicitly share.
  2. Client Portal — Available on Business and Enterprise plans, this provides a white-labeled, polished interface that looks less like internal project management.

For most development teams, guest access provides sufficient functionality and works across all plan tiers. Here’s how to implement it programmatically.

Setting Up Guest Access via API

While you can create guests through the ClickUp UI, automating guest provisioning fits better into developer workflows. Here’s a Python script using the ClickUp API:

import os
import requests

CLICKUP_API_KEY = os.getenv("CLICKUP_API_KEY")
TEAM_ID = os.getenv("CLICKUP_TEAM_ID")

def create_client_guest(email, name, accessible_list_ids):
    """Create a guest user with access to specific lists."""
    url = f"https://api.clickup.com/api/v2/team/{TEAM_ID}/guest"

    payload = {
        "email": email,
        "name": name,
        "can_see_time": True,
        "list_ids": accessible_list_ids
    }

    headers = {
        "Authorization": CLICKUP_API_KEY,
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)
    return response.json()

# Example: Add a client to a specific project list
To set up a ClickUp client portal, create a dedicated space with guest access configured to specific lists, then use ClickUp's API to automate guest provisioning and filter client-facing views. This approach gives remote development teams visibility into project progress while keeping internal technical discussions private.

This approach works well when you need to provision multiple clients across different projects—simply extend the `accessible_list_ids` array to match your project structure.

## Structuring Client-Facing Spaces

Create a dedicated space structure that separates client-visible content from internal development work. A practical folder layout looks like:

Client Projects/ ├── Acme Corp Website/ │ ├── 01_Project_Plan (Client View) │ ├── 02_Milestones (Client View) │ ├── 03_Deliverables (Client View) │ └── Internal_Discussions (Team Only)


The key principle: curate spaces explicitly for clients rather than exposing your entire workspace. Clients should see milestones, deliverables, and status—not sprint planning, bug backlogs, or internal code review discussions.

## Custom Views for Client Visibility

Configure custom views that filter out technical details. Use ClickUp's view API to create client-specific perspectives:

```javascript
// ClickUp API: Create a filtered view for clients
const createClientView = async (listId) => {
 const response = await fetch(`https://api.clickup.com/api/v2/list/${listId}/view`, {
 method: "POST",
 headers: {
 "Authorization": process.env.CLICKUP_API_KEY,
 "Content-Type": "application/json"
 },
 body: JSON.stringify({
 "name": "Client Progress View",
 "filters": {
 "status": ["Not Started", "In Progress", "Complete"],
 "assignees": [] // Show all tasks
 },
 "filter_version": 2,
 "show_subtasks": true,
 "visible_fields": ["name", "due_date", "status", "assignees", "attachments"]
 })
 });

 return response.json();
};

This view includes only task names, due dates, status, assignees, and attachments—stripping out custom fields that might contain cost data, internal priority markers, or technical notes.

Automation Patterns for Client Updates

Automate status updates to reduce manual communication overhead. This Integromat/Make scenario sends weekly summaries to clients:

// Webhook payload handler for weekly client digest
const generateClientDigest = async (clientEmail, projectId) => {
 // Fetch completed tasks from the past week
 const tasks = await clickup.getTasks({
 list_id: projectId,
 filter: {
 statuses: ["complete"],
 date_updated: {
 start: weekAgo(),
 end: now()
 }
 }
 });

 // Format the digest
 const completed = tasks.filter(t => t.status.status === "complete");
 const inProgress = tasks.filter(t => t.status.status === "in_progress");

 return {
 to: clientEmail,
 subject: `Project Update: ${completed.length} tasks completed this week`,
 body: `
Completed: ${completed.map(t => t.name).join(", ")}
In Progress: ${inProgress.map(t => t.name).join(", ")}

View full details: ${dashboardUrl}
 `
 };
};

You can also set up automation within ClickUp itself:

Integrating with External Dashboards

For clients who prefer a custom dashboard outside ClickUp, pull data via the API:

from clickup_api import ClickUpClient
import json

def export_project_status(space_id):
 """Export project status as JSON for external dashboards."""
 client = ClickUpClient(api_key=os.getenv("CLICKUP_API_KEY"))

 # Get all lists in the space
 lists = client.get_lists(space_id)

 status_data = {
 "project_name": space_id,
 "milestones": [],
 "tasks_by_status": {
 "pending": 0,
 "in_progress": 0,
 "complete": 0
 }
 }

 for lst in lists:
 tasks = client.get_tasks(lst.id)
 for task in tasks:
 status = task.status.status.lower().replace(" ", "_")
 if status in status_data["tasks_by_status"]:
 status_data["tasks_by_status"][status] += 1

 return status_data

# Serve via Flask for client dashboard
@app.route("/api/project-status")
def project_status():
 return jsonify(export_project_status("acme_website"))

This pattern works well when you need to embed project status into a client portal running on your own domain.

Permission Auditing for Security

Periodically audit guest permissions to prevent accidental exposure:

def audit_guest_access():
 """List all guests and their accessible resources."""
 client = ClickUpClient(api_key=os.getenv("CLICKUP_API_KEY"))

 team_members = client.get_team_members()
 guests = [m for m in team_members if m.get("is_guest")]

 audit_report = []
 for guest in guests:
 guest_id = guest["id"]
 accessible = client.get_guest_sharedFolders(guest_id)

 audit_report.append({
 "email": guest["email"],
 "name": guest["name"],
 "accessible_folders": [f["name"] for f in accessible],
 "last_active": guest.get("last_active")
 })

 return audit_report

Run this monthly to ensure former clients no longer have access and current clients only see what they need.

Practical Tips for Developer Teams

The client portal setup is not a one-time configuration—treat it as part of your client service infrastructure that evolves based on feedback and usage patterns.

Frequently Asked Questions

Who is this article written for?

This article is written for developers, technical professionals, and power users who want practical guidance. Whether you are evaluating options or implementing a solution, the information here focuses on real-world applicability rather than theoretical overviews.

How current is the information in this article?

We update articles regularly to reflect the latest changes. However, tools and platforms evolve quickly. Always verify specific feature availability and pricing directly on the official website before making purchasing decisions.

Are there free alternatives available?

Free alternatives exist for most tool categories, though they typically come with limitations on features, usage volume, or support. Open-source options can fill some gaps if you are willing to handle setup and maintenance yourself. Evaluate whether the time savings from a paid tool justify the cost for your situation.

Can I trust these tools with sensitive data?

Review each tool’s privacy policy, data handling practices, and security certifications before using it with sensitive data. Look for SOC 2 compliance, encryption in transit and at rest, and clear data retention policies. Enterprise tiers often include stronger privacy guarantees.

What is the learning curve like?

Most tools discussed here can be used productively within a few hours. Mastering advanced features takes 1-2 weeks of regular use. Focus on the 20% of features that cover 80% of your needs first, then explore advanced capabilities as specific needs arise.

Built by theluckystrike — More at zovo.one