> ## Documentation Index
> Fetch the complete documentation index at: https://docs.subtotal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Webhook

> Create a webhook subscribed to the given event names. It starts paused unless `is_active` is true. The response carries the signing secret, which is shown only once; if it is lost, delete the webhook and create a new one.

[Subtotal Connector tool: create\_webhook](/docs/connector/tools.md#create_webhook)

## Access

Call this endpoint with your API key, or with a [Subtotal Connector](/docs/connector/introduction.md) OAuth token that includes `webhooks:write`. A token without `webhooks:write` receives `403 insufficient_scope`. [Partner app](/docs/partner-apps/introduction.md#fixed-permissions) tokens don't include it.

## Example

```bash theme={null}
curl --request POST 'https://api.subtotal.com/webhooks' \
  --header "x-api-key: $SUBTOTAL_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Order sync",
    "url": "https://hooks.example.com/subtotal",
    "event_types": ["connection.activated", "purchase.created"],
    "is_active": true
  }'
```

```json theme={null}
{
  "webhook_id": "01JA7Q2W3E4R5T6Y7U8I9O0P1A",
  "name": "Order sync",
  "url": "https://hooks.example.com/subtotal",
  "is_active": true,
  "event_types": ["connection.activated", "purchase.created"],
  "receive_simulated_events": false,
  "purchase_date_start": null,
  "purchase_date_end": null,
  "created_at": "2026-10-14T17:02:11Z",
  "signing_secret": "Vq3n…"
}
```

A new webhook starts paused unless the request sets `is_active` to `true`, as in this example. Use `event_types` names from [Event types](/docs/webhooks/events.md); an unknown name returns a 422 that lists the valid names.

> [!WARNING]
>
> `signing_secret` is returned only in this response and can't be read back. Store it now and use it to [verify webhook signatures](/docs/webhooks/verifying-signatures.md). If you lose it, delete the webhook and create a new one.

## URL requirements

* `https`, on port 443, with no username or password in the URL.
* The host must resolve, and only to public IP addresses. A host that resolves to a private, loopback, link-local or other non-public address is rejected.

## Errors

| Status | When |
| - | - |
| `422` | A URL that doesn't meet the requirements above, an unknown event type, no event types, a name already used by another of your webhooks, or `purchase_date_start` after `purchase_date_end` |


## OpenAPI

````yaml post /webhooks
openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
servers: []
security: []
paths:
  /webhooks:
    post:
      tags:
        - webhooks
      summary: Create Webhook
      description: >-
        Create a webhook subscribed to the given event names. It starts paused
        unless `is_active` is true. The response carries the signing secret,
        which is shown only once; if it is lost, delete the webhook and create a
        new one.
      operationId: create_webhook_webhooks_post
      parameters:
        - name: authorization
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Authorization
        - name: x-api-key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Api-Key
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateWebhookResponse'
        '422':
          description: >-
            Invalid URL, unknown event type, inverted date window, or duplicate
            name.
components:
  schemas:
    CreateWebhookRequest:
      properties:
        name:
          type: string
          maxLength: 64
          minLength: 1
          title: Name
          description: Unique per account.
        url:
          type: string
          maxLength: 256
          title: Url
          description: HTTPS URL on port 443 that receives the events.
        event_types:
          items:
            type: string
          type: array
          minItems: 1
          title: Event Types
          description: Event names to subscribe to, e.g. `purchase.created`.
        is_active:
          type: boolean
          title: Is Active
          description: >-
            Start delivering immediately. By default the webhook is created
            paused.
          default: false
        receive_simulated_events:
          type: boolean
          title: Receive Simulated Events
          default: false
        purchase_date_start:
          anyOf:
            - type: string
              format: date
            - type: 'null'
          title: Purchase Date Start
        purchase_date_end:
          anyOf:
            - type: string
              format: date
            - type: 'null'
          title: Purchase Date End
      type: object
      required:
        - name
        - url
        - event_types
      title: CreateWebhookRequest
    CreateWebhookResponse:
      properties:
        webhook_id:
          type: string
          title: Webhook Id
        name:
          type: string
          title: Name
        url:
          type: string
          title: Url
        is_active:
          type: boolean
          title: Is Active
        event_types:
          items:
            type: string
          type: array
          title: Event Types
          description: Subscribed event names, e.g. `purchase.created`.
        receive_simulated_events:
          type: boolean
          title: Receive Simulated Events
          description: Also deliver events from the simulator.
        purchase_date_start:
          anyOf:
            - type: string
              format: date
            - type: 'null'
          title: Purchase Date Start
          description: Only purchases on or after this date; null = unbounded.
        purchase_date_end:
          anyOf:
            - type: string
              format: date
            - type: 'null'
          title: Purchase Date End
          description: Only purchases on or before this date; null = unbounded.
        created_at:
          type: string
          format: date-time
          title: Created At
        signing_secret:
          type: string
          title: Signing Secret
          description: >-
            Verifies the `X-Subtotal-Signature` header. Shown only in this
            response; store it now.
      type: object
      required:
        - webhook_id
        - name
        - url
        - is_active
        - event_types
        - receive_simulated_events
        - purchase_date_start
        - purchase_date_end
        - created_at
        - signing_secret
      title: CreateWebhookResponse

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.