Skip to content

User Webhook API Documentation

User-area webhook management endpoints for creating, listing, retrieving, updating, deleting, and inspecting the activity of inbound subscription/unsubscription webhooks owned by the authenticated user.

These webhooks are the user-owned, list-bound webhooks visible at /app/user/webhooks/. They are distinct from the email-gateway webhooks managed under the emailgateway.*webhook* endpoints. Each webhook is bound to a single subscriber list and is triggered (externally) via its auto-generated HashedID to add or remove a subscriber on either a Subscription or Unsubscription event.

List User Webhooks

GET /api/v1/user.webhooks

API Usage Notes

  • Authentication required: User API Key
  • Required permissions: User.Update
  • Rate limit: 100 requests per 60 seconds
  • Legacy endpoint access via /api.php is also supported

Request Body Parameters:

ParameterTypeRequiredDescription
CommandStringYesAPI command: user.webhook.list
SessionIDStringNoSession ID obtained from login
APIKeyStringNoAPI key for authentication
IncludeStatsBooleanNoWhen true, each webhook in the response includes a ReceivedRequestsStats array with the per-day received-request counts for the last 30 days. Default: false
bash
curl -X GET "https://example.com/api/v1/user.webhooks?APIKey=your-api-key&IncludeStats=true"
json
{
  "Success": true,
  "Webhooks": [
    {
      "WebhookID": "6",
      "RelUserID": "1",
      "RelListID": "12",
      "RelListName": "Newsletter Subscribers",
      "Name": "New Subscriber Notifier",
      "Event": "Subscription",
      "HashedID": "f4ca-2c1a-9b7e-8d33-66d2-7cb8-1e09-aa45",
      "Options": {
        "UnsubscribeAll": false
      },
      "ReceivedRequestsStats": {
        "1714003200": 12,
        "1713916800": 8
      }
    }
  ]
}
json
{
  "Errors": [
    {
      "Code": 0,
      "Message": "Authentication failed"
    }
  ]
}
txt
(none — this endpoint has no business-logic error codes; an empty result returns Webhooks: [])

Get a Webhook

GET /api/v1/user.webhook

API Usage Notes

  • Authentication required: User API Key
  • Required permissions: User.Update
  • Rate limit: 100 requests per 60 seconds
  • Legacy endpoint access via /api.php is also supported

Request Body Parameters:

ParameterTypeRequiredDescription
CommandStringYesAPI command: user.webhook.get
SessionIDStringNoSession ID obtained from login
APIKeyStringNoAPI key for authentication
WebhookIDIntegerYesThe ID of the webhook to retrieve. Must be owned by the calling user
bash
curl -X GET "https://example.com/api/v1/user.webhook?APIKey=your-api-key&WebhookID=6"
json
{
  "Success": true,
  "Webhook": {
    "WebhookID": "6",
    "RelUserID": "1",
    "RelListID": "12",
    "Name": "New Subscriber Notifier",
    "Event": "Subscription",
    "HashedID": "f4ca-2c1a-9b7e-8d33-66d2-7cb8-1e09-aa45",
    "Options": {
      "UnsubscribeAll": false
    }
  }
}
json
{
  "Errors": [
    {
      "Code": 2,
      "Message": "Webhook not found"
    }
  ]
}
txt
1: Missing WebhookID parameter
2: Webhook not found (also returned when the webhook exists but is owned by another user — to avoid leaking ownership)

Create a Webhook

POST /api/v1/user.webhook

API Usage Notes

  • Authentication required: User API Key
  • Required permissions: User.Update
  • Rate limit: 100 requests per 60 seconds
  • Legacy endpoint access via /api.php is also supported

The response includes the auto-generated HashedID, which is the value used to construct the externally callable webhook URL (e.g. /system/webhook/<HashedID>/...). Treat it like a secret.

Request Body Parameters:

ParameterTypeRequiredDescription
CommandStringYesAPI command: user.webhook.create
SessionIDStringNoSession ID obtained from login
APIKeyStringNoAPI key for authentication
NameStringYesDisplay name for the webhook
RelListIDIntegerYesID of the subscriber list this webhook is bound to. The list must be owned by the calling user
EventStringYesThe event this webhook handles. Possible values: Subscription, Unsubscription
UnsubscribeAllBooleanNoWhen Event=Unsubscription and this is true, the webhook will unsubscribe the contact from every list owned by the user, not just RelListID. Default: false
bash
curl -X POST https://example.com/api/v1/user.webhook \
  -H "Content-Type: application/json" \
  -d '{
    "Command": "user.webhook.create",
    "APIKey": "your-api-key",
    "Name": "New Subscriber Notifier",
    "RelListID": 12,
    "Event": "Subscription",
    "UnsubscribeAll": false
  }'
json
{
  "Success": true,
  "WebhookID": 6,
  "Webhook": {
    "WebhookID": "6",
    "RelUserID": "1",
    "RelListID": "12",
    "Name": "New Subscriber Notifier",
    "Event": "Subscription",
    "HashedID": "f4ca-2c1a-9b7e-8d33-66d2-7cb8-1e09-aa45",
    "Options": {
      "UnsubscribeAll": false
    }
  }
}
json
{
  "Errors": [
    {
      "Code": 4,
      "Message": "Event must be one of: Subscription, Unsubscription"
    }
  ]
}
txt
1: Missing Name parameter
2: Missing RelListID parameter
3: Missing Event parameter
4: Event must be one of: Subscription, Unsubscription
5: Target subscriber list not found (or not owned by the calling user)
6: Webhook create process failed
7: New webhook could not be retrieved after creation

Update a Webhook

PATCH /api/v1/user.webhook

API Usage Notes

  • Authentication required: User API Key
  • Required permissions: User.Update
  • Rate limit: 100 requests per 60 seconds
  • Legacy endpoint access via /api.php is also supported

The HashedID is preserved across updates, so any external system already calling the webhook URL continues to work after a name, list, or event change.

Request Body Parameters:

ParameterTypeRequiredDescription
CommandStringYesAPI command: user.webhook.update
SessionIDStringNoSession ID obtained from login
APIKeyStringNoAPI key for authentication
WebhookIDIntegerYesThe ID of the webhook to update. Must be owned by the calling user
NameStringYesNew display name for the webhook
RelListIDIntegerYesNew target subscriber list ID. The list must be owned by the calling user
EventStringYesNew event for the webhook. Possible values: Subscription, Unsubscription
UnsubscribeAllBooleanNoWhen Event=Unsubscription and this is true, unsubscribes the contact from every list owned by the user. Omitted: the currently stored value is preserved (the field is not reset to false)
bash
curl -X PATCH https://example.com/api/v1/user.webhook \
  -H "Content-Type: application/json" \
  -d '{
    "Command": "user.webhook.update",
    "APIKey": "your-api-key",
    "WebhookID": 6,
    "Name": "Renamed Webhook",
    "RelListID": 12,
    "Event": "Unsubscription",
    "UnsubscribeAll": true
  }'
json
{
  "Success": true,
  "Webhook": {
    "WebhookID": "6",
    "RelUserID": "1",
    "RelListID": "12",
    "RelListName": "Newsletter Subscribers",
    "Name": "Renamed Webhook",
    "Event": "Unsubscription",
    "HashedID": "f4ca-2c1a-9b7e-8d33-66d2-7cb8-1e09-aa45",
    "Options": {
      "UnsubscribeAll": true
    }
  }
}
json
{
  "Errors": [
    {
      "Code": 6,
      "Message": "Webhook not found"
    }
  ]
}
txt
1: Missing WebhookID parameter
2: Missing Name parameter
3: Missing RelListID parameter
4: Missing Event parameter
5: Event must be one of: Subscription, Unsubscription
6: Webhook not found (also returned when the webhook exists but is owned by another user)
7: Target subscriber list not found (or not owned by the calling user)
8: Webhook could not be retrieved after update (returned with HTTP 500)

Delete a Webhook

DELETE /api/v1/user.webhook

API Usage Notes

  • Authentication required: User API Key
  • Required permissions: User.Update
  • Rate limit: 100 requests per 60 seconds
  • Legacy endpoint access via /api.php is also supported

Deletes the webhook record and its associated daily statistics. This is irreversible — any external system still calling the webhook's HashedID URL will start receiving errors.

Request Body Parameters:

ParameterTypeRequiredDescription
CommandStringYesAPI command: user.webhook.delete
SessionIDStringNoSession ID obtained from login
APIKeyStringNoAPI key for authentication
WebhookIDIntegerYesThe ID of the webhook to delete. Must be owned by the calling user
bash
curl -X DELETE "https://example.com/api/v1/user.webhook?APIKey=your-api-key&WebhookID=6"
json
{
  "Success": true
}
json
{
  "Errors": [
    {
      "Code": 2,
      "Message": "Webhook not found"
    }
  ]
}
txt
1: Missing WebhookID parameter
2: Webhook not found (also returned when the webhook exists but is owned by another user)

Get Webhook Statistics

GET /api/v1/user.webhook.stats

API Usage Notes

  • Authentication required: User API Key
  • Required permissions: User.Update
  • Rate limit: 100 requests per 60 seconds
  • Legacy endpoint access via /api.php is also supported

Returns the per-day activity counters (received, failed, successful) for the webhook, keyed by Y-m-d date. This backs the 30-day chart on the webhook edit page.

Request Body Parameters:

ParameterTypeRequiredDescription
CommandStringYesAPI command: user.webhook.stats
SessionIDStringNoSession ID obtained from login
APIKeyStringNoAPI key for authentication
WebhookIDIntegerYesThe ID of the webhook. Must be owned by the calling user
DaysIntegerNoNumber of most-recent days of stats to return. Clamped to the range 1365. Default: 30
bash
curl -X GET "https://example.com/api/v1/user.webhook.stats?APIKey=your-api-key&WebhookID=6&Days=30"
json
{
  "Success": true,
  "WebhookID": 6,
  "Days": 30,
  "Stats": {
    "2026-04-25": {
      "ID": "412",
      "RelWebhookID": "6",
      "RelUserID": "1",
      "Period": "2026-04-25",
      "ReceivedRequests": "12",
      "FailedRequests": "1",
      "SuccessfulRequests": "11"
    },
    "2026-04-24": {
      "ID": "401",
      "RelWebhookID": "6",
      "RelUserID": "1",
      "Period": "2026-04-24",
      "ReceivedRequests": "8",
      "FailedRequests": "0",
      "SuccessfulRequests": "8"
    }
  }
}
json
{
  "Errors": [
    {
      "Code": 2,
      "Message": "Webhook not found"
    }
  ]
}
txt
1: Missing WebhookID parameter
2: Webhook not found (also returned when the webhook exists but is owned by another user)

Any questions? Contact us.