---
title: "Create Webhook"
method: POST
path: "/v2/webhook"
tags: ["Webhook"]
---

# Create Webhook

`POST /v2/webhook`

# Create Webhook

Create a webhook subscription for an event.  
When that event occurs, your endpoint receives an HTTP `POST`.

## Required Inputs

- `event`: event key from `/webhook/events-list`
- `url`: your public HTTPS endpoint

## Optional Inputs

- `headers`: custom headers to include in delivery requests
- `is_active`: enable/disable delivery without deleting config

## Shared Secret Authentication (Recommended)

To verify webhook authenticity, set `headers["X-Webhook-Secret"]` while creating webhook.

For each delivery, your endpoint receives:
- `X-Webhook-Timestamp`
- `X-Webhook-Signature` in format `v1=<signature>`

Verify using:
- Algorithm: `HMAC-SHA256`
- Signed content: `timestamp + "." + raw_request_body`

Best practice:
- Reject requests with old timestamp (for example older than 5 minutes).
- Use constant-time compare for signatures.
- Process only after signature verification succeeds.

## Important Note

`X-Webhook-Secret` is used only for signing and should not be treated as an incoming authentication header in your receiver.

## Request body

- CreateWebhook
  - `event` 'test' | 'event.catalog.item.add' | 'event.catalog.item.update' | 'event.catalog.item.delete' | 'event.catalog.item.table.row.add' | 'event.catalog.item.table.row.update' | 'event.catalog.item.table.row.delete' | 'event.catalog.custom' | 'event.contract.add' | 'event.contract.update' | 'event.contract.delete' | 'event.project.integration.start' | 'event.project.start' | 'event.project.finish' | 'event.project.approval.submitted' | 'event.project.step.status.change' | 'event.catalog.modification' | 'event.contact.info.upserted' | 'event.integration.status.updated' | 'event.catalog.vendor.manager.modified' | 'event.contract.details.upserted' | 'event.table.row.upserted', required — An enumeration.
  - `url` string, required
  - `headers` object
  - `is_active` boolean

## Response `201`

Successful Response

- WebhookResponse
  - `id` string, required
  - `event` 'test' | 'event.catalog.item.add' | 'event.catalog.item.update' | 'event.catalog.item.delete' | 'event.catalog.item.table.row.add' | 'event.catalog.item.table.row.update' | 'event.catalog.item.table.row.delete' | 'event.catalog.custom' | 'event.contract.add' | 'event.contract.update' | 'event.contract.delete' | 'event.project.integration.start' | 'event.project.start' | 'event.project.finish' | 'event.project.approval.submitted' | 'event.project.step.status.change' | 'event.catalog.modification' | 'event.contact.info.upserted' | 'event.integration.status.updated' | 'event.catalog.vendor.manager.modified' | 'event.contract.details.upserted' | 'event.table.row.upserted', required — An enumeration.
  - `url` string, required
  - `args` object
  - `is_active` boolean
  - `fail_count` integer
  - `created_by_client_id` string

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/expent/apis/expent-apis.md) · [All operations](https://skmtc.dev/expent/apis/expent-apis/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/expent/expent-apis/revisions/ce1d50af5e2c/schema)
