---
title: "Create Webhook"
method: POST
path: "/webhooks"
tags: ["Webhooks"]
---

# Create Webhook

`POST /webhooks`

## Request

- Base URL: `https://app.lettr.com/api`
- URL: `https://app.lettr.com/api/webhooks`
- Auth: HTTP bearer

Create a new webhook to receive event notifications at the specified URL.

## Request body

- StoreWebhookRequest: Request body for creating a webhook
  - `name` string, required: Name of the webhook
  - `url` string, uri, required: URL where webhook events will be sent
  - `auth_type` 'none' | 'basic' | 'oauth2', required: Authentication type for the webhook
  - `auth_username` string: Username for basic authentication (required when auth_type is 'basic')
  - `auth_password` string: Password for basic authentication (required when auth_type is 'basic')
  - `oauth_client_id` string: OAuth2 client ID (required when auth_type is 'oauth2')
  - `oauth_client_secret` string: OAuth2 client secret (required when auth_type is 'oauth2')
  - `oauth_token_url` string, uri: OAuth2 token URL (required when auth_type is 'oauth2')
  - `events_mode` 'all' | 'selected', required: Whether to receive all events or only selected ones
  - `events` string[]: List of event types to receive (required when events_mode is 'selected'). Fully-prefixed names such as `message.delivery` are canonical; short names (`delivery`) and the legacy `engagament.*` prefix are accepted for backwards compatibility and are normalised to the fully-prefixed form.

## Response `201`

Webhook created successfully

- StoreWebhookResponse: Response after creating a webhook
  - `message` string, required: Human-readable response message
  - `data` WebhookView, required: View of a webhook
    - `id` string, required: Unique identifier for the webhook
    - `name` string, required: Name of the webhook
    - `url` string, uri, required: URL where webhook events will be sent
    - `enabled` boolean, required: Whether the webhook is enabled
    - `event_types` string[], nullable: Specific event types the webhook receives (null if all events)
    - `auth_type` string, required: Authentication type for the webhook (none, basic, oauth2)
    - `has_auth_credentials` boolean, required: Whether authentication credentials are configured
    - `last_successful_at` string, date-time, nullable: Timestamp of the last successful webhook delivery
    - `last_failure_at` string, date-time, nullable: Timestamp of the last failed webhook delivery
    - `last_status` 'success' | 'failure' | 'null', nullable: Status of the last delivery attempt (success or failure)

## Other responses

- `400`: Bad request - SparkPost rejected the webhook configuration
- `401`: Unauthorized - Missing or invalid API key
- `409`: Conflict - A webhook with this target URL already exists
- `422`: Validation error
- `500`: Server error - Failed to create webhook
- `503`: Service unavailable - the API key could not be verified, so the request was not processed. This does not mean the key is invalid; retry after the delay given in the Retry-After header.

---

[API](https://skmtc.dev/lettr/apis/lettr-api.md) · [All operations](https://skmtc.dev/lettr/apis/lettr-api/llms.txt) · [OpenAPI document](https://skmtc.dev/lettr/apis/lettr-api/revisions/48ef0dac1ebd?raw)
