---
title: "Add a webhook endpoint. Its signing secret is returned once. | Crossmart Docs"
description: "Documentation for Crossmart, the open-source multichannel platform for sellers and their AI agents."
url: "https://docs.crossmart.io/developers/api/operations/webhookendpointscontroller_create_v1/"
---

# Add a webhook endpoint. Its signing secret is returned once.

POST

/api/v1/workspaces/{workspaceId}/webhook-endpoints

Select code sample

```sh
curl --request POST \
  --url https://api.crossmart.io/api/v1/workspaces/example/webhook-endpoints \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <x-api-key>' \
  --data '{ "url": "https://example.com/crossmart/webhooks", "description": "example", "eventTypes": [ "order.created" ] }'
```

- Crossmart Cloud

Events are POSTed to the URL as JSON, signed in the Crossmart-Signature header.

## Authorizations

- **[api_key](https://docs.crossmart.io/developers/api/#api_key)**
- **[cookie](https://docs.crossmart.io/developers/api/#cookie)**
- **[bearer](https://docs.crossmart.io/developers/api/#bearer)**

## Parameters

### Path Parameters

**workspaceId**

required

string

## Request Bodyrequired

Media typeapplication/json

object

**url**

required

Where events are POSTed. https and a public address; plain http only outside production.

string

### Example

```plaintext
https://example.com/crossmart/webhooks
```

**description**

string

nullable <= 500 characters

**eventTypes**

required

The events to receive. `webhook.test` cannot be subscribed to.

Array\<string>

Allowed values: order.created order.updated inventory.stock_changed listing.published listing.failed listing.removed product.created product.updated product.deleted webhook.test

## Responses

### 201

Media typeapplication/json

object

**endpoint**

required

object

**id**

required

string format: uuid

**url**

required

string

**description**

required

string

nullable

**eventTypes**

required

Array\<string>

Allowed values: order.created order.updated inventory.stock_changed listing.published listing.failed listing.removed product.created product.updated product.deleted webhook.test

**enabled**

required

False when turned off by someone or after repeated failures

boolean

**disabledReason**

required

MANUAL: turned off by someone. FAILING: turned off by Crossmart.

string

Allowed values: MANUAL FAILING

**disabledAt**

required

string format: date-time

nullable

**consecutiveFailures**

required

Failed attempts since the last delivery that went through

number

**lastDelivery**

required

The latest delivery attempt, whatever event it carried; null before the first

object

**attemptedAt**

required

string format: date-time

**outcome**

required

SUCCEEDED: the endpoint answered 2xx. FAILED: anything else, or no answer.

string

Allowed values: SUCCEEDED FAILED

**responseStatus**

required

Null when no response came: a timeout or a connection error

number

nullable

**error**

required

Why the attempt failed; null on success

string

nullable

**previousSecretExpiresAt**

required

Until then deliveries are also signed with the secret the last rotation replaced

string format: date-time

nullable

**createdAt**

required

string format: date-time

**updatedAt**

required

string format: date-time

**secret**

required

The signing secret. Shown once; store it now.

string

#### Example

```json
{
  "endpoint": {
    "url": "https://example.com/crossmart/webhooks",
    "description": "Order notifications to n8n",
    "eventTypes": [
      "order.created"
    ],
    "disabledReason": "MANUAL",
    "lastDelivery": {
      "outcome": "SUCCEEDED",
      "responseStatus": 200,
      "error": "The endpoint answered with HTTP 503"
    }
  },
  "secret": "whsec_3q2-7wEXAMPLEsecretVALUE0123456789abcdef"
}
```

### 400

The URL is not https (in production), or not a public address

### 402

The organization’s plan does not allow this (`ENTITLEMENTS_ENFORCED` is on). `code` and `feature` say why; upgrading the plan resolves it.

Media typeapplication/json

object

**statusCode**

required

number

**error**

required

string

**code**

required

string

Allowed values: plan_limit_reached plan_feature_not_included

**message**

required

string

**feature**

required

string

Allowed values: active_listings channel_connections workspaces members api_keys webhook_endpoints ai_credits autonomous_agents bring_your_own_key

**plan**

required

The code of the organization’s plan

string

**limit**

required

Null is unlimited

number

nullable

**usage**

required

number

**requested**

required

How many more the request asked for

number

#### Example

```json
{
  "statusCode": 402,
  "error": "Payment Required",
  "code": "plan_limit_reached",
  "message": "The Free plan includes 2 connected channels, and 2 are in use. Upgrade the plan to add more.",
  "feature": "active_listings",
  "plan": "free"
}
```

### 503

The server has no CREDENTIALS_MASTER_KEY to encrypt secrets with
