Webhooks

Webhooks allow your application to receive real-time HTTP callbacks when events occur in the chat system. Configure a webhook URL, subscribe to specific event types, and sphere-chat will POST payloads to your endpoint. Payloads contain IDs only -- never message content -- to ensure privacy.

Webhook security

Every webhook delivery includes a signature header for verification:

X-Sphere-Signature: t=1708790100,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

The signature format is t=timestamp,v1=signature where:

  • t is the Unix timestamp of when the delivery was sent
  • v1 is the HMAC-SHA256 signature computed over {timestamp}.{payload_body} using your webhook secret

Verify the signature by computing HMAC-SHA256(secret, "{t}.{raw_body}") and comparing the result to the v1 value. Reject deliveries where the timestamp is more than 5 minutes old to prevent replay attacks.

Retry policy

Failed deliveries are retried with exponential backoff:

  • Name
    Attempt 1
    Description

    Immediate (0 seconds).

  • Name
    Attempt 2
    Description

    After 30 seconds.

  • Name
    Attempt 3
    Description

    After 2 minutes.

  • Name
    Attempt 4
    Description

    After 10 minutes.

  • Name
    Attempt 5
    Description

    After 30 minutes.

  • Name
    DLQ
    Description

    After 5 failed attempts, the delivery moves to the dead letter queue (DLQ).

After 10 consecutive failures (across different events), the webhook is automatically disabled. Re-enable it by updating the webhook via PATCH.


The webhook model

Properties

  • Name
    id
    Type
    string
    Description

    Unique UUID identifier for the webhook.

  • Name
    url
    Type
    string
    Description

    The HTTPS endpoint that receives webhook deliveries.

  • Name
    events
    Type
    array
    Description

    List of event types this webhook subscribes to (e.g., message.created, notification.created).

  • Name
    secret
    Type
    string
    Description

    The secret key used to compute HMAC-SHA256 signatures. Only returned on creation.

  • Name
    is_active
    Type
    boolean
    Description

    Whether the webhook is currently active. Auto-disabled after 10 consecutive failures.

  • Name
    created_at
    Type
    timestamp
    Description

    ISO 8601 timestamp of when the webhook was created.

  • Name
    updated_at
    Type
    timestamp
    Description

    ISO 8601 timestamp of the last update.


GET/chat/api/v1/webhooks

List webhooks

Retrieve all webhooks configured for the authenticated user's tenant.

Request

GET
/chat/api/v1/webhooks
curl https://your-sphere.example.com/chat/api/v1/webhooks \
  -H "Authorization: Bearer {token}"

Response

{
  "data": [
    {
      "id": "wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
      "url": "https://api.yourapp.com/webhooks/sphere-chat",
      "events": ["message.created", "notification.created"],
      "is_active": true,
      "created_at": "2026-02-20T10:00:00Z",
      "updated_at": "2026-02-20T10:00:00Z"
    }
  ]
}

POST/chat/api/v1/webhooks

Create webhook

Create a new webhook subscription. The URL must use HTTPS. The secret is returned only once in the creation response -- store it securely for signature verification.

Required attributes

  • Name
    url
    Type
    string
    Description

    The HTTPS URL to receive webhook deliveries.

  • Name
    events
    Type
    array
    Description

    Array of event types to subscribe to. Available events: message.created, message.updated, message.deleted, notification.created, conversation.created, conversation.updated, member.added, member.removed.

  • Name
    secret
    Type
    string
    Description

    A secret key for HMAC-SHA256 signature generation. Must be at least 32 characters.

Request

POST
/chat/api/v1/webhooks
curl -X POST https://your-sphere.example.com/chat/api/v1/webhooks \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.yourapp.com/webhooks/sphere-chat",
    "events": ["message.created", "notification.created"],
    "secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
  }'

Response

{
  "data": {
    "id": "wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
    "url": "https://api.yourapp.com/webhooks/sphere-chat",
    "events": ["message.created", "notification.created"],
    "secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
    "is_active": true,
    "created_at": "2026-02-24T15:00:00Z",
    "updated_at": "2026-02-24T15:00:00Z"
  }
}

GET/chat/api/v1/webhooks/{id}

Get webhook

Retrieve the details of a specific webhook by its UUID. The secret is not included in the response for security reasons.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the webhook to retrieve.

Request

GET
/chat/api/v1/webhooks/{id}
curl https://your-sphere.example.com/chat/api/v1/webhooks/wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer {token}"

Response

{
  "data": {
    "id": "wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
    "url": "https://api.yourapp.com/webhooks/sphere-chat",
    "events": ["message.created", "notification.created"],
    "is_active": true,
    "created_at": "2026-02-24T15:00:00Z",
    "updated_at": "2026-02-24T15:00:00Z"
  }
}

PATCH/chat/api/v1/webhooks/{id}

Update webhook

Update an existing webhook's URL, event subscriptions, secret, or active state. Use this endpoint to re-enable a webhook that was auto-disabled due to consecutive failures.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the webhook to update.

Optional attributes

  • Name
    url
    Type
    string
    Description

    New HTTPS URL for webhook deliveries.

  • Name
    events
    Type
    array
    Description

    Updated list of event types to subscribe to.

  • Name
    secret
    Type
    string
    Description

    New secret key for HMAC-SHA256 signatures.

  • Name
    is_active
    Type
    boolean
    Description

    Set to true to re-enable a disabled webhook.

Request

PATCH
/chat/api/v1/webhooks/{id}
curl -X PATCH https://your-sphere.example.com/chat/api/v1/webhooks/wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["message.created", "message.deleted", "notification.created"],
    "is_active": true
  }'

Response

{
  "data": {
    "id": "wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
    "url": "https://api.yourapp.com/webhooks/sphere-chat",
    "events": ["message.created", "message.deleted", "notification.created"],
    "is_active": true,
    "created_at": "2026-02-24T15:00:00Z",
    "updated_at": "2026-02-24T15:10:00Z"
  }
}

DELETE/chat/api/v1/webhooks/{id}

Delete webhook

Permanently delete a webhook. All pending deliveries and delivery history are discarded. This action cannot be undone.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the webhook to delete.

Request

DELETE
/chat/api/v1/webhooks/{id}
curl -X DELETE https://your-sphere.example.com/chat/api/v1/webhooks/wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer {token}"

Response (204 No Content)

// No response body

POST/chat/api/v1/webhooks/{id}/test

Send test delivery

Send a test delivery to the webhook URL. This is useful for verifying that your endpoint is reachable and correctly validates the HMAC signature. The test payload uses the test.ping event type.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the webhook to test.

Request

POST
/chat/api/v1/webhooks/{id}/test
curl -X POST https://your-sphere.example.com/chat/api/v1/webhooks/wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890/test \
  -H "Authorization: Bearer {token}"

Response

{
  "data": {
    "delivery_id": "del-f6a7b8c9-d0e1-2345-fabC-456789012345",
    "status": "delivered",
    "response_code": 200,
    "response_time_ms": 145
  }
}

GET/chat/api/v1/webhooks/{id}/deliveries

List delivery history

Retrieve the delivery history for a specific webhook. Each delivery record includes the HTTP status code, response time, and delivery status.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the webhook.

Optional attributes

  • Name
    status
    Type
    string
    Description

    Filter by delivery status: delivered, failed, or pending.

  • Name
    cursor
    Type
    string
    Description

    Cursor for pagination.

  • Name
    limit
    Type
    integer
    Description

    Number of deliveries to return per page. Default is 50.

Request

GET
/chat/api/v1/webhooks/{id}/deliveries
curl -G https://your-sphere.example.com/chat/api/v1/webhooks/wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890/deliveries \
  -H "Authorization: Bearer {token}" \
  -d status=failed \
  -d limit=10

Response

{
  "data": [
    {
      "id": "del-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
      "event": "message.created",
      "status": "failed",
      "response_code": 500,
      "response_time_ms": 3021,
      "attempt": 3,
      "next_retry_at": "2026-02-24T15:12:00Z",
      "created_at": "2026-02-24T15:00:00Z"
    },
    {
      "id": "del-2b3c4d5e-6f7a-8901-bcde-f12345678901",
      "event": "notification.created",
      "status": "failed",
      "response_code": 0,
      "response_time_ms": 30000,
      "attempt": 5,
      "next_retry_at": null,
      "created_at": "2026-02-24T14:50:00Z"
    }
  ]
}

POST/chat/api/v1/webhooks/{id}/deliveries/{deliveryId}/retry

Retry failed delivery

Manually retry a failed webhook delivery. This immediately attempts to resend the payload to the webhook URL, bypassing the automatic retry schedule.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the webhook.

  • Name
    deliveryId
    Type
    string
    Description

    The UUID of the delivery to retry.

Request

POST
/chat/api/v1/webhooks/{id}/deliveries/{deliveryId}/retry
curl -X POST https://your-sphere.example.com/chat/api/v1/webhooks/wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890/deliveries/del-1a2b3c4d-5e6f-7890-abcd-ef1234567890/retry \
  -H "Authorization: Bearer {token}"

Response

{
  "data": {
    "delivery_id": "del-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
    "status": "delivered",
    "response_code": 200,
    "response_time_ms": 89
  }
}

GET/chat/api/v1/webhooks/dlq

List dead letter queue

Retrieve items in the dead letter queue (DLQ). Deliveries move to the DLQ after exhausting all automatic retry attempts (5 attempts). DLQ items can be manually retried or discarded.

Optional attributes

  • Name
    cursor
    Type
    string
    Description

    Cursor for pagination.

  • Name
    limit
    Type
    integer
    Description

    Number of DLQ items to return per page. Default is 50.

Request

GET
/chat/api/v1/webhooks/dlq
curl -G https://your-sphere.example.com/chat/api/v1/webhooks/dlq \
  -H "Authorization: Bearer {token}" \
  -d limit=10

Response

{
  "data": [
    {
      "id": "dlq-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
      "webhook_id": "wh-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
      "event": "notification.created",
      "attempts": 5,
      "last_response_code": 0,
      "last_error": "Connection timeout after 30000ms",
      "payload_summary": {
        "event_type": "notification.created",
        "conversation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
      },
      "failed_at": "2026-02-24T15:30:00Z",
      "created_at": "2026-02-24T14:50:00Z"
    }
  ]
}

POST/chat/api/v1/webhooks/dlq/{id}/retry

Retry DLQ item

Manually retry a dead letter queue item. This immediately attempts to deliver the payload to the webhook URL. If successful, the item is removed from the DLQ. If it fails again, it remains in the DLQ for future retry.

URL parameters

  • Name
    id
    Type
    string
    Description

    The UUID of the DLQ item to retry.

Request

POST
/chat/api/v1/webhooks/dlq/{id}/retry
curl -X POST https://your-sphere.example.com/chat/api/v1/webhooks/dlq/dlq-1a2b3c4d-5e6f-7890-abcd-ef1234567890/retry \
  -H "Authorization: Bearer {token}"

Response

{
  "data": {
    "id": "dlq-1a2b3c4d-5e6f-7890-abcd-ef1234567890",
    "status": "delivered",
    "response_code": 200,
    "response_time_ms": 112
  }
}

Was this page helpful?