Agent skill
Teamwork Webhooks Skill
Receive and verify Teamwork.com Projects webhooks. Use when setting up Teamwork webhook handlers, debugging X-Projects-Signature verification, or handling events like TASK.CREATED, TASK.COMPLETED, PROJECT.CREATED, or COMMENT.CREATED from Teamwork Projects.
Install this skill
npx skills add hookdeck/webhook-skills --skill teamwork-webhooks
Covers Teamwork.com Projects webhooks, Version 2 only. Teamwork Desk and Teamwork Spaces webhooks are documented separately and are not covered here.
When to Use This Skill
- How do I receive Teamwork Projects webhooks?
- How do I verify the Teamwork
X-Projects-Signatureheader? - How do I handle
TASK.CREATED,TASK.COMPLETED, orPROJECT.CREATEDevents? - Why is my Teamwork webhook signature verification failing?
- Why does my Teamwork webhook have no signature header?
Verification (core)
When a webhook has a token, Teamwork computes an HMAC-SHA256 of the raw POST body keyed with that token (as UTF-8 bytes) and sends it hex-encoded in the X-Projects-Signature header (no prefix, no timestamp). The token is optional in Teamwork, so you must choose Version 2 and set one, or no signature is sent.
Node (check the header is exactly 64 hex chars before Buffer.from(x, 'hex'), because invalid hex silently truncates):
const crypto = require('crypto');
function verifyTeamworkWebhook(rawBody, signature, token) {
if (!signature || !token || !/^[0-9a-f]{64}$/i.test(signature)) return false;
const expected = crypto.createHmac('sha256', token).update(rawBody).digest();
return crypto.timingSafeEqual(Buffer.from(signature, 'hex'), expected);
}
Python (compare_digest on bytes, so a non-ASCII header gives 401, not 500):
import hmac, hashlib
def verify_teamwork_webhook(raw_body: bytes, signature: str | None, token: str | None) -> bool:
if not signature or not token:
return False
expected = hmac.new(token.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature.lower().encode("utf-8"), expected.encode("utf-8"))
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Teamwork has no official SDK helper for webhook verification, so all three examples verify manually. Express examples read the body with express.raw({ type: '*/*' }) so any content type verifies.
Common Event Types
The event name arrives in the X-Projects-Event header in uppercase ENTITY.ACTION form. The body has no event field, only an eventCreator object and the entity (for example task, project, comment).
| Event | Triggered When |
|---|---|
TASK.CREATED | A task is created |
TASK.UPDATED | A task is updated |
TASK.COMPLETED | A task is completed |
TASK.DELETED | A task is deleted |
PROJECT.CREATED | A project is created |
COMMENT.CREATED | A comment is added |
MILESTONE.COMPLETED | A milestone is completed |
TIME.CREATED | Time is logged |
All delete events share one payload: { "id", "projectId", "eventCreator" }. See references/overview.md for the full entity/action list.
Important Headers and Fields
| Item | Description |
|---|---|
X-Projects-Signature header | Hex HMAC-SHA256 of the raw body, keyed with the webhook token |
X-Projects-Event header | Event name, e.g. TASK.CREATED |
eventCreator (body) | id, firstName, lastName, avatar of the user who triggered the event |
Respond 200 within 5 seconds. Any other status (including 3xx) counts as a failure: Teamwork retries hourly, up to 3 attempts, and deactivates the webhook after three discarded events. Queue work and acknowledge immediately.
Environment Variables
TEAMWORK_WEBHOOK_TOKEN=your_webhook_token # the token set on the Version 2 webhook
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 teamwork --path /webhooks/teamwork
Use the Hookdeck URL as the webhook URL in Teamwork.
Hookdeck setup
Only Teamwork.com Projects webhooks are supported. Use Version 2 webhooks and set a token; Teamwork signs with it. Enter the same token as the signing secret on the Hookdeck source. See references/setup.md.
Reference Materials
- references/overview.md - Teamwork webhook concepts, event list, payload shape
- references/setup.md - Create a Version 2 webhook with a token, Hookdeck setup
- references/verification.md - Signature verification details and gotchas