We changed our name!
Clubhouse is now called Shortcut!
This change impacts Outgoing Webhooks in two ways:
- All links in Webhook payloads which were to
clubhouse.io
domains are toshortcut.com
domains instead. - The
Clubhouse-Signature
header is now deprecated.
It is now calledPayload-Signature
.
For now we are including both headers (with the same signature value),
butClubhouse-Signature
will be removed on or after November 13th, 2021.
Please update your application to readPayload-Signature
instead.
If you did not configure your webhook with a secret to sign payloads with,
you are not affected by this change.
Shortcut Outgoing Webhooks
Introduction
You can use webhooks to get notified about events that happen in your Shortcut workspace. If you have any trouble or questions about using our Outgoing Webhooks API, check out our Help Center or just contact us—we’re happy to help!
Status
This is the v1 version of our Outgoing Webhook API. There may be breaking changes, but we will document them in a Change Log section on this page.
Use Cases
An Outgoing Webhook allows you to register a URL that Shortcut notifies whenever any change happens in your Shortcut workspace. Webhooks track changes made by users in your account, and changes made via API token requests. Webhooks allow you to use events that occur in Shortcut to trigger events in other services.
Here are some ideas to get you started…
- If a Story is moved to Ready for QA, send a Slack message to a #ready-for-qa channel.
- If a Story is moved to Ready for Deploy, execute a CI build or integration test script.
- If a Story in a particular Epic has a deadline is set, post a reminder in Slack three days before it’s due.
- If a Story is moved into or out of an Epic or Iteration or has its estimate changed after work is started, create a notification in Slack to start a team conversation.
Events
Shortcut’s outgoing webhooks fire whenever Stories or Epics are created, updated, or deleted. This includes all changes to comments and tasks as well, and even workflow state changes initiated by version control integrations like GitHub.
Webhook Event Format
Example Response
{
"id": "595285dc-9c43-4b9c-a1e6-0cd9aff5b084",
"changed_at": "2017-06-27T16:20:44Z",
"primary_id": 16927,
"member_id": "56d8a839-1c52-437f-b981-c3a15a11d6d4",
"version": "v1",
"actions": [
{
"id": 16927,
"entity_type": "story",
"action": "update",
"name": "test story",
"changes": {
"started": {
"new": true,
"old": false
},
"workflow_state_id": {
"new": 1495,
"old": 1493
},
"owner_ids": {
"adds": ["56d8a839-1c52-437f-b981-c3a15a11d6d4"]
}
}
}
],
"references": [
{
"id": 1495,
"entity_type": "workflow-state",
"name": "Ready for Deploy"
},
{
"id": 1493,
"entity_type": "workflow-state",
"name": "Ready for Dev"
}
]
}
Each Webhook API event has the following properties:
Name | Type |
---|---|
id | UUID |
primary_id | UUID or Integer (if present†) |
member_id | UUID |
changed_at | Date |
actions | [ Action, … ] |
references | [ Reference, … ] |
† NOTE: In cases where there is no single, unambiguous “primary” entity responsible for the changes in a webhook event, the primary_id
field will not be present in the payload. However, each entity in the actions
array will have an id
field that is always populated and can be used to identify entities of interest.
The actions array represents actions that changed Shortcut objects in your workspace. It will include changes to the primary object and other objects affected by the event.
Each action object in the actions array follows a standard format. Each action has an id
field which is the entity’s id, an entity_type
field with values like "story"
or "epic"
, and an action
field describing the type of action like "update"
or "create"
.
Included in the action object is a changes object. The changes object includes details of the changes, e.g., the old and new values of attributes that where changed in the event.
Experimenting with an example server will be the fastest and easiest way to understand how Shortcut activity is captured in Webhook API events.
Signature
If you provide a secret when you create the Outgoing Webhook, events will include an HTTP header named Payload-Signature
. The value of this header is a cryptographic hash in hexadecimal form encoded in UTF-8.
The signature is computed by the HMAC-SHA-256 algorithm. The message
is the HTTP request body encoded in UTF-8. The secret
is the secret string you provided, also encoded in UTF-8.
Testing
Example Self-hosted Server
Example Server
const http = require("node:http");
const hostname = "127.0.0.1";
const port = 3000;
const server = http.createServer((req, res) => {
let now = Date.now();
if (req.method === "POST") {
let data = [];
req.on("data", (chunk) => {
data.push(chunk);
});
req.on("end", () => {
console.log(now, "Shortcut Webhook Event");
console.log(JSON.parse(data));
});
}
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.end(`{"webhook_received_at":${now}}\n`);
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
With the server code on the right side of this page running locally on your computer, you can use Tailscale Funnels or ngrok to generate a publicly-addressable URL that will proxy HTTP requests to your local machine. Then you can supply that publicly-addressable URL in your Shortcut Webhook settings to see local logging of Shortcut webhook events. Refer to the Help Center instructions for Shortcut Webhooks for screenshots and details.
NOTE: Tailscale and ngrok are third-party services—we cannot guarantee the privacy of information transmitted there.
Hosted Server
The simplest way to see the data being delivered to your inbound webhook is to use a hosted solution like Webhook.site. A hosted server allows you to easily test and inspect incoming HTTP requests.
NOTE: Webhook.site is a third-party service—we cannot guarantee the privacy of information transmitted there.