Create webhook endpoint
Creates an outgoing webhook endpoint that receives the chosen events at an HTTPS address. Sends no messages to contacts. Returns the endpoint with its signing secret, shown only once; use it to verify every delivery.
POST /v1/webhook-endpoints
| Permission | webhooks:write (all permissions) |
| Risk | Write (no outside effect) |
| Idempotency-Key | Not needed (how it works) |
| Safe to repeat | Not safe to repeat blindly: the server keeps no key for this call, so a repeat does the work again. |
| Rate limit class | write (120 requests per minute per key) |
| Confirmation | None |
| MCP tool | Not available in MCP |
| Since version | 2026-10-25 |
#What it does
- Changes data in your account. It does not send messages to contacts.
#Request
Body (JSON)
| Name | Type | Required | Description |
|---|---|---|---|
url | string | yes | HTTPS address, port 443 only, no credentials in the address, no internal networks, no redirects. up to 2000 characters |
description | string | no | Your own note about this endpoint. up to 200 characters; default "" |
enabled_events | array of string | yes | Event types to receive (see the events page) or ["*"] for all available events. Planned events are rejected. Your key needs the read permission of each event. up to 30 items |
#Examples
Example 1
curl -X POST "https://api.smartchat.marketing/v1/webhook-endpoints" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/smartchat",
"description": "Quickstart",
"enabled_events": [
"webhook.test"
]
}'import os
import requests
response = requests.post(
"https://api.smartchat.marketing/v1/webhook-endpoints",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
json={
"url": "https://example.com/hooks/smartchat",
"description": "Quickstart",
"enabled_events": [
"webhook.test",
],
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/webhook-endpoints", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com/hooks/smartchat",
"description": "Quickstart",
"enabled_events": [
"webhook.test"
]
}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (201):
{
"object": "webhook_endpoint",
"id": "whe_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"url": "https://example.com/hooks/smartchat",
"description": "Quickstart",
"enabled_events": [
"webhook.test"
],
"status": "active",
"disabled_reason": null,
"secret_hint": "whsec_...x9Qa",
"consecutive_failures": 0,
"last_success_at": "2026-10-25T09:45:00Z",
"last_failure_at": null,
"secret_previous_expires_at": null,
"created_at": "2026-10-25T09:41:07Z",
"updated_at": "2026-10-25T09:45:00Z",
"secret": "whsec_3Zk0sQ1mYv9bT7cWl2nR8xJdE4fGhUaPoIyKtVq5LwM"
}Example 2
curl -X POST "https://api.smartchat.marketing/v1/webhook-endpoints" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/smartchat",
"description": "Order system",
"enabled_events": [
"contact.created",
"message.received"
]
}'import os
import requests
response = requests.post(
"https://api.smartchat.marketing/v1/webhook-endpoints",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
json={
"url": "https://example.com/hooks/smartchat",
"description": "Order system",
"enabled_events": [
"contact.created",
"message.received",
],
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/webhook-endpoints", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com/hooks/smartchat",
"description": "Order system",
"enabled_events": [
"contact.created",
"message.received"
]
}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (201):
{
"object": "webhook_endpoint",
"id": "whe_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"url": "https://example.com/hooks/smartchat",
"description": "Order system",
"enabled_events": [
"contact.created",
"message.received"
],
"status": "active",
"disabled_reason": null,
"secret_hint": "whsec_...x9Qa",
"consecutive_failures": 0,
"last_success_at": "2026-10-25T09:45:00Z",
"last_failure_at": null,
"secret_previous_expires_at": null,
"created_at": "2026-10-25T09:41:07Z",
"updated_at": "2026-10-25T09:45:00Z",
"secret": "whsec_3Zk0sQ1mYv9bT7cWl2nR8xJdE4fGhUaPoIyKtVq5LwM"
}#Response
Status 201. Every response has the headers Request-Id, SmartChat-Version and X-RateLimit-*.
| Name | Type | Description |
|---|---|---|
object | string | Always "webhook_endpoint". always webhook_endpoint |
id | string | Webhook endpoint ID. |
url | string | HTTPS address that receives the events. up to 2000 characters |
description | string | Your own note about this endpoint. up to 200 characters |
enabled_events | array of string | Event types this endpoint receives, or ["*"] for all available events. up to 30 items |
status | string | active and degraded receive events. paused and disabled do not; call enable_webhook_endpoint. one of: active, degraded, paused, disabled |
disabled_reason | string or null | Why the endpoint was paused or disabled. Null while it is working. up to 60 characters |
secret_hint | string | Last 4 characters of the signing secret, for example whsec_...abcd. up to 20 characters |
consecutive_failures | integer | Failed delivery attempts in a row since the last success. 0 to 1000000 |
last_success_at | string or null | Time of the last successful delivery. up to 40 characters; format date-time |
last_failure_at | string or null | Time of the last failed delivery attempt. up to 40 characters; format date-time |
secret_previous_expires_at | string or null | While a secret rotation is running: when the old secret stops signing. Otherwise null. up to 40 characters; format date-time |
created_at | string | When the endpoint was created. up to 40 characters; format date-time |
updated_at | string | When the endpoint was last changed. up to 40 characters; format date-time |
secret | string | Signing secret (whsec_...). Store it now; it is never shown again. up to 80 characters |
#Errors
| Code | Status | When |
|---|---|---|
api_key_expired | 401 | This API key has expired. |
api_key_invalid | 401 | This API key is not valid. |
api_key_revoked | 401 | This API key was revoked. |
authentication_required | 401 | No API key was sent. Send 'Authorization: Bearer <key>'. |
insufficient_scope | 403 | This key lacks a required permission. |
ip_not_allowed | 403 | This IP address is not allowed for this key. |
conflict | 409 | The state of the object does not allow this. |
webhook_limit_reached | 409 | The account has the maximum of 20 webhook endpoints. |
validation_failed | 422 | A field is not valid. |
webhook_url_invalid | 422 | The URL is not allowed. Only https, port 443 and no internal networks. |
rate_limited | 429 | Too many requests. Wait and try again. |
internal_error | 500 | Something went wrong on our side. |
All errors use one format.