---
title: "Create a webhook"
method: POST
path: "/v1/webhooks"
tags: ["Webhooks"]
---

# Create a webhook

`POST /v1/webhooks`

## Request

- Base URL: `https://hcti.io`
- URL: `https://hcti.io/v1/webhooks`
- Auth: HTTP basic

Creates a webhook that receives the selected organization events. Subscribing to an event requires read access to its resource, for example templates:read for template events. A signing secret is generated for every webhook and returned as signing_secret in this response, even when signing is disabled. Store it securely to verify signed deliveries; updates, reads, lists, and MCP responses never return it. Creating an enabled webhook queues a webhook_test delivery, identified by test_event_id in the response. Secret parameter values are never returned.

**Rate limit:** 20 requests per minute per organization, shared across all operations in the `webhook:write` group and all API keys belonging to that organization.

## Request body

- CreateOrUpdateWebhookRequest: Complete configuration for creating or updating a webhook. Updates replace the configuration: omitted parameters are removed, and secret values must be resent or kept with retain_value: true. Changing the URL, parameters, or signing setting of an enabled webhook, or enabling it, sends a webhook_test delivery.
  - `name` string, required: Display name for the webhook, up to 255 characters. Leading and trailing whitespace is removed.
  - `url` string, required: HTTPS endpoint that receives deliveries, up to 2048 characters, for example https://hooks.example.com/hcti. https:// is assumed when no scheme is given. Must use a DNS host name on the default HTTPS port, without credentials, a query string, or a fragment. Add query parameters through parameters.
  - `disabled` boolean: Whether the webhook is disabled. Disabled webhooks receive no deliveries, and queued deliveries are not sent. Defaults to false.
  - `events` WebhookEventType[], required: Complete list of event types to deliver. Subscribing to an event requires read access to its resource, for example templates:read for template events. webhook_test cannot be subscribed to. An empty array delivers only test events.
  - `parameters` WebhookParameterRequest[], nullable: Up to 20 headers and query parameters added to every delivery, in any order. Header names and values may total at most 8 KiB in UTF-8, and the URL with its encoded query parameters at most 8192 characters. Replaces the complete list; omitted, null, or [] removes them.
    - `location` 'header' | 'query_parameter', required: Where a webhook parameter is sent on each delivery.
    - `key` string, required: Header or query parameter name, up to 512 UTF-8 bytes, unique within its location. Header names must be valid HTTP tokens. Transport headers such as Host, Content-Length, and Content-Type, and headers starting with X-HCTI- or Webhook-, are reserved.
    - `secret` boolean: Whether the value is secret. Secret values are stored encrypted, never returned by the API, and kept out of delivery history. Use this for credentials such as an Authorization header. Defaults to false.
    - `value` string, nullable: Parameter value, up to 4 KiB in UTF-8. Required unless retain_value is true. An empty string is a valid value.
    - `retain_value` boolean: Keep the stored secret value on update instead of resending it. Requires secret: true, no value, and an existing secret with the same location and key. Secrets cannot be kept when the URL changes; resend them instead. Defaults to false.
  - `signing_enabled` boolean: Whether to sign deliveries with this webhook's signing secret. The secret is generated when the webhook is created, returned only in the REST API create response, and can also be copied from the dashboard. Defaults to false.

## Response `200`

OK

- Webhook: A webhook's endpoint, subscriptions, and delivery parameters. Secret parameter values are never returned. The signing secret is returned only when creating a webhook through the REST API.
  - `id` string, required: Webhook ID.
  - `name` string, required: Display name for the webhook.
  - `enabled` boolean: Whether the webhook is enabled. Disabled webhooks receive no deliveries.
  - `url` string, required: HTTPS endpoint that receives deliveries, without query parameters.
  - `events` WebhookEventType[], required: Event types delivered to this webhook.
  - `parameters` WebhookParameter[], required: Headers and query parameters added to every delivery. Secret values are omitted.
    - `location` 'header' | 'query_parameter', required: Where a webhook parameter is sent on each delivery.
    - `key` string, required: Header or query parameter name.
    - `secret` boolean: Whether the value is secret. Secret values are stored encrypted and never returned.
    - `value` string, nullable: The parameter value, or null for secret parameters.
  - `signing_enabled` boolean: Whether deliveries are signed with this webhook's signing secret.
  - `signing_secret` string, nullable: Signing secret for verifying deliveries. Returned only in the REST API create response, even when signing is disabled. Store it securely; updates, reads, lists, and MCP responses omit this field.
  - `config_version` union: Version of the delivery settings (URL, parameters, and signing). It increases when any of them change, and each delivery attempt records the version it used.
    - integer
    - string, int32
  - `created_at` string, date-time: UTC timestamp when the webhook was created.
  - `updated_at` string, date-time: UTC timestamp when the webhook was last updated.
  - `test_event_id` string, nullable: Event ID of the webhook_test delivery this create or update queued, matching the event_id the endpoint receives. Null when no test was queued, and always null outside create and update responses.

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `429`: Too Many Requests

## Changes

- **2026-11-03** `100550373ae1`: 1 info
  - added the optional property `signing_secret` to the response with the `200` status
- **2026-10-30** `146fbf859b2d`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/htmlcsstoimage/apis/html-css-to-image-api/changes/v1/webhooks/post.md)

---

[API](https://skmtc.dev/htmlcsstoimage/apis/html-css-to-image-api.md) - [All operations](https://skmtc.dev/htmlcsstoimage/apis/html-css-to-image-api/llms.txt) - [OpenAPI document](https://skmtc.dev/htmlcsstoimage/apis/html-css-to-image-api/revisions/100550373ae1?raw)
