# Autotask Webhooks

## When to Use This Skill

* How do I receive Autotask webhooks?
* How do I verify the Autotask `X-Hook-Signature` header?
* Why is my Autotask webhook signature verification failing?
* How do I handle Ticket, Company or Contact Create/Update/Delete callouts?
* How do I create an Autotask webhook with a `SecretKey` through the REST API?

## Verification (core)

Autotask signs the **raw request body** with **HMAC-SHA1**, keyed with the `SecretKey` set when the webhook was created (up to 64 characters). The digest is **base64** (keep the `=` padding) and is sent as `X-Hook-Signature: sha1=<base64>`, for example `sha1=UaDXFl2DRDu9dnINVkFle7y5uAE=`. There is no timestamp and Autotask ships no verification SDK, so verify manually.

```javascript
const crypto = require('crypto');

function verifyAutotaskWebhook(rawBody, header, secret) {
  if (typeof header !== 'string' || !header.startsWith('sha1=')) return false;
  const received = header.slice('sha1='.length);
  const expected = crypto.createHmac('sha1', secret).update(rawBody).digest('base64');
  // Equal-length UTF-8 buffers, no lenient base64 decode of the header
  const a = Buffer.from(received, 'utf8');
  const b = Buffer.from(expected, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

```

In Python, compare bytes so a non-ASCII header returns 401 instead of raising a 500: `hmac.compare_digest(expected.encode(), received.encode())`.

Always verify the **raw body**. In Express use `express.raw({ type: '*/*' })` so any content type is verified; don't `JSON.parse` first.

> **For complete handlers with tests**, see [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/autotask-webhooks/examples/express/), [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/autotask-webhooks/examples/nextjs/), [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/autotask-webhooks/examples/fastapi/).

## Payload and Events

Autotask has no event-name string. Each callout is a JSON POST with `Action`, `Guid`, `EntityType`, `Id`, `Fields`, `EventTime`, `SequenceNumber` and `PersonID`. Dispatch on `EntityType` and `Action`.

| `Action` | Triggered When | `Fields` |
| --- | --- | --- |
| `Create` | A record is created | All subscribed, non-null fields and UDFs |
| `Update` | A subscribed field changes | Fields and UDFs that changed |
| `Delete` | A record is deleted | Base payload only |
| `Deactivated` | The webhook is deactivated | Base payload only; `Guid` identifies the webhook |

Entities that support webhooks: Companies, Contacts, Assets (Configuration Items), Tickets and Ticket Notes. The examples handle `Company`, `Contact`, `Ticket` and `TicketNote`.

> **For the full reference**, see [Creating a webhook](https://www.autotask.net/help/developerhelp/Content/APIs/Webhooks/Webhooks_Creating.htm).

## Environment Variables

```bash
AUTOTASK_WEBHOOK_SECRET=your_webhook_secret_key_here   # the SecretKey set when creating the webhook

```

## Local Development

```bash
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 autotask --path /webhooks/autotask

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/autotask-webhooks/references/overview.md) - Autotask webhook concepts, entities, payload fields
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/autotask-webhooks/references/setup.md) - Creating a webhook through the REST API
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/autotask-webhooks/references/verification.md) - Signature verification details and gotchas