Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions apps/docs/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2801,6 +2801,52 @@ export function LinqIcon(props: SVGProps<SVGSVGElement>) {
)
}

export function ClickUpIcon(props: SVGProps<SVGSVGElement>) {
const id = useId()
const bodyGradientId = `clickup_body_${id}`
const arrowGradientId = `clickup_arrow_${id}`
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 54.8 65.8' fill='none'>
<linearGradient
id={bodyGradientId}
gradientUnits='userSpaceOnUse'
x1='0'
y1='15.0492'
x2='54.8446'
y2='15.0492'
gradientTransform='matrix(1 0 0 -1 0 69.3604)'
>
<stop offset='0' stopColor='#8930FD' />
<stop offset='1' stopColor='#49CCF9' />
</linearGradient>
<linearGradient
id={arrowGradientId}
gradientUnits='userSpaceOnUse'
x1='1.1953'
y1='53.166'
x2='53.7447'
y2='53.166'
gradientTransform='matrix(1 0 0 -1 0 69.3604)'
>
<stop offset='0' stopColor='#FF02F0' />
<stop offset='1' stopColor='#FFC800' />
</linearGradient>
<path
fillRule='evenodd'
clipRule='evenodd'
fill={`url(#${bodyGradientId})`}
d='M0,50.6l10.1-7.8c5.4,7,11.1,10.3,17.4,10.3c6.3,0,11.9-3.2,17-10.2l10.3,7.6c-7.4,10-16.6,15.3-27.3,15.3C16.9,65.8,7.6,60.5,0,50.6z'
/>
<path
fillRule='evenodd'
clipRule='evenodd'
fill={`url(#${arrowGradientId})`}
d='M27.5,16.9l-18,15.5l-8.3-9.7L27.6,0l26.2,22.7l-8.4,9.6L27.5,16.9z'
/>
</svg>
)
}

export function LinearIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
Expand Down Expand Up @@ -3745,6 +3791,38 @@ export const SakanaIcon = (props: SVGProps<SVGSVGElement>) => (
</svg>
)

export const NvidiaIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
{...props}
height='1em'
viewBox='30 28 280 172'
width='1em'
xmlns='http://www.w3.org/2000/svg'
>
<title>NVIDIA</title>
<path
d='M82.211,102.414c0,0,22.504-33.203,67.437-36.638V53.73c-49.769,3.997-92.867,46.149-92.867,46.149s24.41,70.565,92.867,77.026v-12.804C99.411,157.781,82.211,102.414,82.211,102.414z M149.648,138.637v11.726c-37.968-6.769-48.507-46.237-48.507-46.237s18.23-20.195,48.507-23.47v12.867c-0.023,0-0.039-0.007-0.058-0.007c-15.891-1.907-28.305,12.938-28.305,12.938S128.243,131.445,149.648,138.637 M149.648,31.512V53.73c1.461-0.112,2.922-0.207,4.391-0.257c56.582-1.907,93.449,46.406,93.449,46.406s-42.343,51.488-86.457,51.488c-4.043,0-7.828-0.375-11.383-1.005v13.739c3.04,0.386,6.192,0.613,9.481,0.613c41.051,0,70.738-20.965,99.484-45.778c4.766,3.817,24.278,13.103,28.289,17.168c-27.332,22.883-91.031,41.329-127.144,41.329c-3.481,0-6.824-0.211-10.11-0.528v19.306h156.032V31.512H149.648z M149.648,80.656V65.777c1.446-0.101,2.903-0.179,4.391-0.226c40.688-1.278,67.382,34.965,67.382,34.965s-28.832,40.043-59.746,40.043c-4.449,0-8.438-0.715-12.028-1.922V93.523c15.84,1.914,19.028,8.911,28.551,24.786l21.18-17.859c0,0-15.461-20.277-41.524-20.277C155.021,80.172,152.31,80.371,149.648,80.656'
fill='#77B900'
/>
</svg>
)

export const ZaiIcon = (props: SVGProps<SVGSVGElement>) => (
<svg {...props} height='1em' viewBox='0 0 30 30' width='1em' xmlns='http://www.w3.org/2000/svg'>
<title>Z.ai</title>
<path
d='M24.51,28.51H5.49c-2.21,0-4-1.79-4-4V5.49c0-2.21,1.79-4,4-4h19.03c2.21,0,4,1.79,4,4v19.03C28.51,26.72,26.72,28.51,24.51,28.51z'
fill='#2D2D2D'
/>
<path
d='M15.47,7.1l-1.3,1.85c-0.2,0.29-0.54,0.47-0.9,0.47h-7.1V7.09C6.16,7.1,15.47,7.1,15.47,7.1z'
fill='#FFFFFF'
/>
<polygon fill='#FFFFFF' points='24.3,7.1 13.14,22.91 5.7,22.91 16.86,7.1' />
<path d='M14.53,22.91l1.31-1.86c0.2-0.29,0.54-0.47,0.9-0.47h7.09v2.33H14.53z' fill='#FFFFFF' />
</svg>
)

export function MetaIcon(props: SVGProps<SVGSVGElement>) {
const id = useId()
const gradient1Id = `meta_gradient_1_${id}`
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/components/ui/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
ClayIcon,
ClerkIcon,
ClickHouseIcon,
ClickUpIcon,
CloudFormationIcon,
CloudflareIcon,
CloudWatchIcon,
Expand Down Expand Up @@ -273,6 +274,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
clay: ClayIcon,
clerk: ClerkIcon,
clickhouse: ClickHouseIcon,
clickup: ClickUpIcon,
cloudflare: CloudflareIcon,
cloudformation: CloudFormationIcon,
cloudwatch: CloudWatchIcon,
Expand Down
81 changes: 81 additions & 0 deletions apps/docs/content/docs/en/integrations/clickup-service-account.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: ClickUp API Tokens
description: Connect ClickUp to Sim with a personal API token — ideally created from a dedicated service user for production workflows
---

import { Callout } from 'fumadocs-ui/components/callout'
import { Step, Steps } from 'fumadocs-ui/components/steps'
import { Image } from '@/components/ui/image'
import { FAQ } from '@/components/ui/faq'

ClickUp personal API tokens let your workflows authenticate without an OAuth consent flow. A token gives full parity with the ClickUp API — everything Sim's ClickUp blocks can do over OAuth works with a token.

Tokens are bound to the user who creates them: every action a workflow takes is attributed to that user, and the token stops working if the user is deactivated or removed from the workspace. For production workflows, create the token from a dedicated service user (e.g. `sim-bot@yourcompany.com`) rather than a personal account.

## Prerequisites

A ClickUp account with access to the workspaces your workflows need. Any user can generate a personal API token from their settings.

## Creating the API Token

<Steps>
<Step>
Log in as the service user, click your avatar in ClickUp, and open **Settings**

{/* TODO(screenshot): ClickUp avatar menu with Settings highlighted */}
</Step>
<Step>
In the sidebar, go to **Apps** (labeled **API Token** in some plans)
</Step>
<Step>
Click **Generate** to create your personal token

{/* TODO(screenshot): ClickUp Apps page with the Generate API token button visible */}
</Step>
<Step>
Copy the token — it starts with `pk_` — and store it somewhere safe.
</Step>
</Steps>

<Callout type="warn">
The API token carries the creating user's full access to every workspace they belong to. Treat it like a password — do not commit it to source control or share it publicly. Sim encrypts the token at rest.
</Callout>

## Adding the API Token to Sim

<Steps>
<Step>
Open your workspace **Settings** and go to the **Integrations** tab
</Step>
<Step>
Search for "ClickUp Service Account" and click it, then click **Add to Sim** and choose **Add API token**

{/* TODO(screenshot): Integrations page with "ClickUp Service Account" in the service list */}
</Step>
<Step>
Paste the API token (`pk_...`) and optionally set a display name and description

{/* TODO(screenshot): Add ClickUp API token dialog with the token filled in */}
</Step>
<Step>
Click **Add API token**. Sim verifies the token by fetching the authorized user from ClickUp — if it fails, you'll see a specific error explaining what went wrong.
</Step>
</Steps>

The token is encrypted before being stored.

## Using the Service Account in Workflows

Add a ClickUp block to your workflow. In the credential dropdown, your ClickUp service account appears alongside any OAuth credentials. Select it and configure the block as you normally would.

{/* TODO(screenshot): ClickUp block in a workflow with the service account selected as the credential */}

The block calls the ClickUp API (`api.clickup.com`) with the token. Everything the workflow does — creating tasks, adding comments, uploading attachments — is attributed to the user who created the token.

<FAQ items={[
{ question: "Does ClickUp have real service accounts?", answer: "Not for API tokens — every token is tied to a user. The closest equivalent is creating a dedicated service user in your workspace and generating the token from that account, so workflows aren't attributed to (or broken by) a real person's account." },
{ question: "Does the token expire?", answer: "No — personal API tokens are long-lived and don't auto-rotate. They stay valid until regenerated, or until the user who created them is deactivated or removed from the workspace." },
{ question: "What happens if the token's user leaves the company?", answer: "Tokens are user-bound, so deactivating the user kills the token and every workflow using it starts failing with authentication errors. This is exactly why production tokens should come from a dedicated service user." },
{ question: "Which workspaces can the token reach?", answer: "Every workspace the creating user belongs to. Use the Get Workspaces operation to see what the token can access, and remember that removing the user from a workspace also removes the token's access to it." },
{ question: "How do I rotate the token?", answer: "Regenerate the token from the same service user in ClickUp (regenerating invalidates the old one immediately), then update the credential in Sim with the new token." },
]} />
Loading
Loading