SKILL.md
ClickUp Install & Auth
Overview
Configure ClickUp API v2 authentication. ClickUp supports two auth methods: Personal API Tokens (for personal/server-side use) and OAuth 2.0 (for multi-user apps). There is no official SDK -- use direct HTTP calls to https://api.clickup.com/api/v2/.
Prerequisites
- ClickUp account (any plan: Free Forever, Unlimited, Business, Business Plus, Enterprise)
- Node.js 18+ or Python 3.10+
- For OAuth 2.0: registered app in ClickUp's integrations dashboard
Authentication Methods
Method 1: Personal API Token (Recommended for Server-Side)
Generate at: ClickUp Settings > Apps > API Token
Personal tokens never expire and are tied to your ClickUp user account.
# Store token securely
echo 'CLICKUP_API_TOKEN=pk_12345678_ABCDEFGHIJKLMNOPQRSTUVWXYZ' >> .env
echo '.env' >> .gitignore
// src/clickup/client.ts
const CLICKUP_BASE = 'https://api.clickup.com/api/v2';
async function clickupRequest(path: string, options: RequestInit = {}) {
const response = await fetch(`${CLICKUP_BASE}${path}`, {
...options,
headers: {
'Authorization': process.env.CLICKUP_API_TOKEN!,
'Content-Type': 'application/json',
...options.headers,
},
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new ClickUpError(response.status, error.err ?? error.ECODE ?? 'Unknown error');
}
return response.json();
}
Method 2: OAuth 2.0 (For Multi-User Apps)
OAuth 2.0 uses the Authorization Code grant type. Access tokens currently do not expire.
// Step 1: Redirect user to ClickUp authorization
const CLIENT_ID = process.env.CLICKUP_CLIENT_ID!;
const REDIRECT_URI = 'https://yourapp.com/auth/clickup/callback';
function getAuthUrl(): string {
return `https://app.clickup.com/api?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`;
}
// Step 2: Exchange authorization code for access token
async function exchangeCodeForToken(code: string): Promise<string> {
const response = await fetch('https://api.clickup.com/api/v2/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: process.env.CLICKUP_CLIENT_ID,
client_secret: process.env.CLICKUP_CLIENT_SECRET,
code,
}),
});
const data = await response.json();
// Response: { "access_token": "12345678_abcdefghijklmnopqrstuvwxyz" }
return data.access_token;
}
