Skip to content
Dashboard

Create a webhook

client.webhooks.create(WebhookCreateParams { name, topics, url, 3 more } params, RequestOptionsoptions?): Webhook { id, createdAt, description, 11 more }
POST/v2/webhooks

Creates a new webhook to receive event notifications.

Request Body

FieldTypeRequiredDescription
namestringYesHuman-readable name (max 100 chars)
urlstringYesWebhook endpoint URL (must be HTTPS)
descriptionstringNoOptional description (max 500 chars)
topicsstring[]YesEvent topics to subscribe to
requestConfigobjectNoRequest configuration
requestConfig.headersobjectNoCustom headers to send (max 10)

Available Topics

  • post.created - When a new feedback post is created
  • post.updated - When a feedback post is updated
  • post.deleted - When a feedback post is deleted
  • post.voted - When a feedback post receives a vote
  • ticket.created - When a new ticket is created
  • ticket.updated - When a ticket is updated
  • ticket.deleted - When a ticket is deleted
  • changelog.published - When a changelog is published
  • comment.created - When a comment is created
  • comment.updated - When a comment is updated
  • comment.deleted - When a comment is deleted

Response

Returns the created webhook object including the signing secret.

Example Request

{
  "name": "Production Webhook",
  "url": "https://example.com/webhooks",
  "description": "Handles all production events",
  "topics": ["post.created", "post.updated", "comment.created"],
  "requestConfig": {
    "timeoutMs": 10000,
    "headers": {
      "X-Custom-Header": "value"
    }
  }
}

Example Response

{
  "object": "webhook",
  "id": "507f1f77bcf86cd799439011",
  "name": "Production Webhook",
  "url": "https://example.com/webhooks",
  "secret": "whsec_abc123def456ghi789",
  "topics": ["post.created", "post.updated", "comment.created"],
  "status": "active",
  ...
}

Limits

Each organization has a maximum number of webhooks (default: 10). Creating a webhook when the limit is reached will return a 400 error.

Version Availability

This endpoint is only available in API version 2026-01-01.nova and newer.

ParametersExpand Collapse
params: WebhookCreateParams { name, topics, url, 3 more }
name: string

Body param: Human-readable name for the webhook

minLength1
maxLength255
topics: Array<"post.created" | "post.updated" | "post.deleted" | 24 more>

Body param: Array of event topics to subscribe to

One of the following:
"post.created"
"post.updated"
"post.deleted"
"post.voted"
"ticket.created"
"ticket.updated"
"ticket.deleted"
"changelog.published"
"comment.created"
"comment.updated"
"comment.deleted"
"conversation.user.created"
"conversation.user.replied"
"conversation.admin.replied"
"conversation.admin.closed"
"conversation.handover_requested"
"conversation.admin.assigned"
"conversation.admin.noted"
"conversation.admin.snoozed"
"conversation.admin.unsnoozed"
"conversation.admin.opened"
"conversation.priority.updated"
"conversation.deleted"
"conversation.contact.attached"
"conversation.contact.detached"
"conversation.read"
"conversation_part.redacted"
url: string

Body param: Webhook endpoint URL (must be HTTPS)

description?: string

Body param: Optional description of the webhook purpose

maxLength500
requestConfig?: WebhookRequestConfigInput { headers }

Body param: Request configuration for webhook delivery

headers?: Record<string, string>

Custom headers to send with webhook requests (max 10)

featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"

Header param: API version for this request. Defaults to your organization’s configured API version if not specified.

One of the following:
"2026-01-01.nova"
"2025-12-12.clover"
ReturnsExpand Collapse
Webhook { id, createdAt, description, 11 more }
id: string

Unique identifier

createdAt: string

ISO timestamp when the webhook was created

description: string | null

Optional description of the webhook purpose

health: Health { avgResponseTime, consecutiveFailures, errorsSinceLastSuccess, 2 more }
avgResponseTime: number

Average response time in milliseconds

consecutiveFailures: number

Number of consecutive delivery failures

errorsSinceLastSuccess: number

Number of errors since last successful delivery

lastResponseTime: number

Last response time in milliseconds

lastSuccessAt: string | null

ISO timestamp of last successful delivery

lastStatus: LastStatus | null

Last delivery attempt status

code: number

HTTP status code from last delivery attempt

message: string

Status message from last delivery attempt

timestamp: string

ISO timestamp of last status update

name: string

Human-readable webhook name

object: "webhook"

Object type identifier

requestConfig: RequestConfig { timeoutMs, headers }
timeoutMs: number

Request timeout in milliseconds (1000-30000)

minimum1000
maximum30000
headers?: Record<string, string>

Custom headers to send with webhook requests

secret: string

Webhook signing secret for verifying payloads

status: "active" | "paused" | "suspended"

Current status of the webhook

One of the following:
"active"
"paused"
"suspended"
topics: Array<"post.created" | "post.updated" | "post.deleted" | 24 more>

Array of event topics the webhook subscribes to

One of the following:
"post.created"
"post.updated"
"post.deleted"
"post.voted"
"ticket.created"
"ticket.updated"
"ticket.deleted"
"changelog.published"
"comment.created"
"comment.updated"
"comment.deleted"
"conversation.user.created"
"conversation.user.replied"
"conversation.admin.replied"
"conversation.admin.closed"
"conversation.handover_requested"
"conversation.admin.assigned"
"conversation.admin.noted"
"conversation.admin.snoozed"
"conversation.admin.unsnoozed"
"conversation.admin.opened"
"conversation.priority.updated"
"conversation.deleted"
"conversation.contact.attached"
"conversation.contact.detached"
"conversation.read"
"conversation_part.redacted"
updatedAt: string

ISO timestamp when the webhook was last updated

url: string

Webhook endpoint URL

version: string

API version for webhook payloads

Create a webhook

import Featurebase from 'featurebase-node';

const client = new Featurebase({
  apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted
});

const webhook = await client.webhooks.create({
  name: 'Production Webhook',
  topics: ['post.created', 'post.updated'],
  url: 'https://example.com/webhooks',
});

console.log(webhook.id);
{
  "id": "507f1f77bcf86cd799439011",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "description": "Handles all production events",
  "health": {
    "avgResponseTime": 200,
    "consecutiveFailures": 0,
    "errorsSinceLastSuccess": 0,
    "lastResponseTime": 150,
    "lastSuccessAt": "2025-01-15T10:30:00.000Z"
  },
  "lastStatus": {
    "code": 200,
    "message": "Success",
    "timestamp": "2025-01-15T10:30:00.000Z"
  },
  "name": "Production Webhook",
  "object": "webhook",
  "requestConfig": {
    "timeoutMs": 5000,
    "headers": {
      "X-Custom-Header": "value"
    }
  },
  "secret": "whsec_abc123def456ghi789",
  "status": "active",
  "topics": [
    "post.created",
    "post.updated"
  ],
  "updatedAt": "2025-01-15T10:30:00.000Z",
  "url": "https://example.com/webhooks",
  "version": "1.0"
}
Returns Examples
{
  "id": "507f1f77bcf86cd799439011",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "description": "Handles all production events",
  "health": {
    "avgResponseTime": 200,
    "consecutiveFailures": 0,
    "errorsSinceLastSuccess": 0,
    "lastResponseTime": 150,
    "lastSuccessAt": "2025-01-15T10:30:00.000Z"
  },
  "lastStatus": {
    "code": 200,
    "message": "Success",
    "timestamp": "2025-01-15T10:30:00.000Z"
  },
  "name": "Production Webhook",
  "object": "webhook",
  "requestConfig": {
    "timeoutMs": 5000,
    "headers": {
      "X-Custom-Header": "value"
    }
  },
  "secret": "whsec_abc123def456ghi789",
  "status": "active",
  "topics": [
    "post.created",
    "post.updated"
  ],
  "updatedAt": "2025-01-15T10:30:00.000Z",
  "url": "https://example.com/webhooks",
  "version": "1.0"
}