Skip to main content

ClickUp Integration

This guide covers both sides of the ClickUp integration for administrators and contributors:

  • Configuring routing — wiring ClickUp lists, the Platform custom field, and the Alakai stage field into config.json.
  • Testing locally — exercising the flow on your machine, from a quick signed mock to a full real-task round-trip.

For the end-user view of how the flow behaves, see ClickUp Automations.


Configuring routing

How the flow is triggered

Alakai listens for ClickUp taskStatusUpdated webhooks and acts only when a task transitions into the Alakai Ready status (case-insensitive). The routing key is the webhook ID: each connected list registers its own webhook, and Alakai uses the incoming webhook_id to find the list — and therefore the project — the task belongs to.

Resolution happens in this order:

  1. Webhook → list. Match the payload's webhook_id against projects.<project>.clickup.lists[].webhookId. No match → discarded (webhook_not_mapped).
  2. List → application. Resolve which application (repo) the task targets — directly if the list has one app, or via the Platform custom field if it serves several (see below).
  3. Stage fork. Read the Alakai stage custom field to decide between the prompt-PR flow and direct implementation.

Throughout, the application must have workflows.clickupTaskPromptPr: true or the task is discarded.

Config schema

The relevant schema lives in core/src/config/repoWorkflowConfig.ts. The ClickUp-specific pieces:

Project levelprojects.<project>.clickup:

FieldRequiredDescription
space.idYesNumeric ClickUp space ID (string).
space.nameNoDisplay name, used for logging and /clickup-task name matching.
taskCreation.allowedSlackUserIdsNoSlack users allowed to use /clickup-task for this project.
taskCreation.defaultListIdNoDefault list for /clickup-task.
lists[]Yes (for this flow)One entry per connected list — see below.

List entryprojects.<project>.clickup.lists[]:

FieldRequiredDescription
idYesNumeric ClickUp list ID (string).
nameYesHuman-readable list name.
webhookIdYes (for this flow)The ClickUp webhook ID registered for this list. This is the routing key.
platformFieldOnly when the list serves multiple apps{ id, name? } — the ClickUp custom field ID of the Platform dropdown.
defaultApplicationNoApplication key used when the Platform field is empty/unset on the task.

Application levelprojects.<project>.applications.<app>.clickup:

FieldRequiredDescription
taskStatusTrigger.listIdYes (for this flow)Must match a clickup.lists[].id in the same project. Associates this app with that list.
taskStatusTrigger.platformFieldValueOnly on shared listsThe Platform dropdown option label that routes a task to this app (e.g. backend, ios). Matched case-insensitively.

The application must also set workflows.clickupTaskPromptPr: true.

Example 1 — list mapped to a single repo

No Platform field needed. Every task in the list routes to the one application.

{
"projects": {
"demo": {
"displayName": "Demo Project",
"clickup": {
"space": { "id": "90120056789", "name": "Engineering" },
"lists": [
{
"id": "901200100",
"name": "Backlog",
"webhookId": "wh_abc123xyz789"
}
]
},
"applications": {
"demo-app": {
"repo": "your-org/your-repo",
"baseBranch": "main",
"workflows": { "clickupTaskPromptPr": true },
"clickup": {
"taskStatusTrigger": { "listId": "901200100" }
}
}
}
}
}
}

Example 2 — one list shared across repos (Platform routing)

The list carries a platformField, and each application declares the platformFieldValue that routes to it. defaultApplication handles tasks where the Platform field was left blank.

{
"projects": {
"demo": {
"clickup": {
"space": { "id": "90120056789", "name": "Engineering" },
"lists": [
{
"id": "901200100",
"name": "Backlog",
"webhookId": "wh_abc123xyz789",
"platformField": { "id": "cf_platform_field_id", "name": "Platform" },
"defaultApplication": "backend-app"
}
]
},
"applications": {
"backend-app": {
"repo": "your-org/backend-repo",
"baseBranch": "main",
"workflows": { "clickupTaskPromptPr": true },
"clickup": {
"taskStatusTrigger": { "listId": "901200100", "platformFieldValue": "backend" }
}
},
"ios-app": {
"repo": "your-org/ios-repo",
"baseBranch": "main",
"workflows": { "clickupTaskPromptPr": true },
"clickup": {
"taskStatusTrigger": { "listId": "901200100", "platformFieldValue": "ios" }
}
}
}
}
}
}

Application resolution rules

For a task arriving on a given list:

  • List has no platformField:
    • Exactly one app references the list via taskStatusTrigger.listId → route to it.
    • More than one → ambiguous_application, discarded.
    • None → no_application_for_list, discarded.
  • List has a platformField:
    • Read the task's value for that field ID and match its option label against each app's platformFieldValue → route to the match.
    • No match → platform_not_mapped, discarded.
    • Field empty/unset and defaultApplication set → route to the default app.
    • Field empty/unset and no default → platform_field_missing, discarded.

The Alakai stage field

The stage is read from a custom field named Alakai stage (case-insensitive lookup by name — it does not need to be declared in config.json).

ValueBehaviour
Prompting (or empty)Generate a docs(prompts): clickup-<taskId> PR; merging it triggers the implementation pipeline.
ImplementationSkip the prompt PR; enqueue a direct implementation run using the task description as the inline spec.

Direct implementation requires a non-empty description and a spec under the inline payload limit (~230 KB). Otherwise Alakai posts a comment on the task explaining the problem and does not run.

Webhook registration & secrets

Each connected list needs its own ClickUp webhook, registered against POST /clickup/webhook. The webhook ID returned at registration goes into lists[].webhookId, and its signing secret is stored in the CLICKUP_WEBHOOK_SECRETS map (keyed by webhook ID) — in .env locally, or AWS Secrets Manager in production. The local testing guide walks through registering a webhook with ngrok.


Testing locally

To exercise the flow locally — a quick signed mock, or a full real-task round-trip with ngrok — see the dedicated guide: Test ClickUp "Alakai Ready" Flow Locally.