> ## Documentation Index
> Fetch the complete documentation index at: https://developers.sendlayer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Managing Webhooks

> Learn how to create, retrieve, and delete webhooks using the SendLayer API

## Overview

Webhooks are HTTP callbacks that allow SendLayer to notify your application in real-time when specific email events occur. Instead of polling the API to check for updates, webhooks automatically send data to your specified URL when events happen, such as when an email is opened, clicked, or bounced.

## How Webhooks Work

1. **Setup**: You create a webhook by providing a URL endpoint and specifying which events you want to monitor
2. **Monitoring**: SendLayer monitors your email activity for the specified events
3. **Notification**: When an event occurs, SendLayer sends an HTTP POST request to your webhook URL with event data
4. **Processing**: Your application receives and processes the webhook data

## Prerequisites

* [Authorize your domain](https://sendlayer.com/docs/authorizing-your-domain/)
* [Create or retrieve your API key](https://sendlayer.com/docs/managing-api-keys/)
* A publicly accessible webhook endpoint URL
* [Install the SendLayer SDK](/quickstart/installation)

## Creating a Webhook

To create a webhook, you need to specify the event type you want to monitor and the URL where SendLayer should send notifications.

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { SendLayer } from 'sendlayer';

  const sendlayer = new SendLayer('your-api-key');

  const params = {
    url: 'https://your-domain.com/webhook',
    event: 'open'
  };

  const response = await sendlayer.Webhooks.create(params);
  console.log('Webhook created with ID:', response.NewWebhookID);
  ```

  ```python Python theme={null}
  from sendlayer import SendLayer

  sendlayer = SendLayer('your-api-key')

  params = {
      "url": "https://your-domain.com/webhook",
      "event": "open"
  }

  response = sendlayer.Webhooks.create(**params)
  print(f"Webhook created with ID: {response['NewWebhookID']}")
  ```

  ```php PHP theme={null}
  <?php
  require_once 'vendor/autoload.php';

  use SendLayer\SendLayer;

  $sendlayer = new SendLayer('your-api-key');

  $params = [
    'url' => 'https://your-domain.com/webhook',
    'event' => 'open'
  ];

  $response = $sendlayer->Webhooks->create($params);
  ```

  ```ruby Ruby theme={null}
  require 'sendlayer'

  sendlayer = SendLayer::SendLayer.new('your-api-key')

  webhook = sendlayer.webhooks.create(
    url: 'https://your-domain.com/webhook',
    event: 'open'
  )
  ```

  ```go Go theme={null}
  sl := sendlayer.New("your-api-key")

  webhook, err := sl.Webhooks.Create(&sendlayer.WebhookCreateRequest{
    WebhookURL: "https://your-domain.com/webhook",
    Event:      "open",
  })
  ```

  ```bash cURL theme={null}
  curl --request POST \
    --url https://console.sendlayer.com/api/v1/webhooks \
    --header 'Authorization: Bearer <apiKey>' \
    --header 'Content-Type: application/json' \
    --data '{
    "Event": "open",
    "WebhookURL": "https://your-domain.com/webhook"
  }'
  ```
</CodeGroup>

<Warning>Replace `<apiKey>` with your actual SendLayer API key in the request header.</Warning>

### Available Event Types

You can monitor the following email events:

| Event         | Description                                       |
| ------------- | ------------------------------------------------- |
| `delivery`    | Email successfully delivered to recipient's inbox |
| `open`        | Recipient opened the email                        |
| `click`       | Recipient clicked a link in the email             |
| `bounce`      | Email failed to deliver and bounced back          |
| `unsubscribe` | Recipient unsubscribed from emails                |
| `complaint`   | Recipient marked email as spam                    |

## Retrieving Webhooks

You can retrieve all webhooks associated with your account to see their current status and configuration.

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { SendLayer } from 'sendlayer';

  const sendlayer = new SendLayer('your-api-key');

  const webhooks = await sendlayer.Webhooks.get();
  console.log('Webhooks:', webhooks.Webhooks);
  ```

  ```python Python theme={null}
  from sendlayer import SendLayer

  sendlayer = SendLayer('your-api-key')

  webhooks = sendlayer.Webhooks.get()
  print("Webhooks:", webhooks['Webhooks'])
  ```

  ```php PHP theme={null}
  <?php
  require_once 'vendor/autoload.php';

  use SendLayer\SendLayer;

  $sendlayer = new SendLayer('your-api-key');

  $webhooks = $sendlayer->Webhooks->get();
  ```

  ```ruby Ruby theme={null}
  sendlayer = SendLayer::SendLayer.new('your-api-key')
  webhooks = sendlayer.webhooks.get
  ```

  ```go Go theme={null}
  sl := sendlayer.New("your-api-key")
  webhooks, err := sl.Webhooks.Get()
  ```

  ```bash cURL theme={null}
  curl --request GET \
    --url https://console.sendlayer.com/api/v1/webhooks \
    --header 'Authorization: Bearer <apiKey>'
  ```
</CodeGroup>

### Get Webhook Response Format

When you retrieve webhooks, you'll receive data in this format:

```json theme={null}
{
  "Webhooks": [
    {
      "WebhookID": "23718",
      "CreatedAt": "2025-04-11 09:43:07",
      "UpdatedAt": "2025-04-11 09:43:07",
      "Status": "Enabled",
      "WebhookURL": "https://your-domain.com/webhook",
      "Event": "open",
      "LastResponseCode": "200",
      "LastResponseBody": "",
      "LastResponseAt": "2025-04-11 10:15:30",
      "LastResponseTryCounter": "0"
    }
  ]
}
```

## Deleting a Webhook

You can delete a webhook by providing its ID. This action cannot be undone.

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { SendLayer } from 'sendlayer';

  const sendlayer = new SendLayer('your-api-key');

  const webhookId = 23718;
  await sendlayer.Webhooks.delete(webhookId);
  console.log('Webhook deleted successfully');
  ```

  ```python Python theme={null}
  from sendlayer import SendLayer

  sendlayer = SendLayer('your-api-key')

  webhook_id = 23718
  sendlayer.Webhooks.delete(webhook_id)
  print("Webhook deleted successfully")
  ```

  ```php PHP theme={null}
  <?php
  require_once 'vendor/autoload.php';

  use SendLayer\SendLayer;

  $sendlayer = new SendLayer('your-api-key');

  $webhookId = 23718;
  $sendlayer->Webhooks->delete($webhookId);
  ```

  ```ruby Ruby theme={null}
  sendlayer = SendLayer::SendLayer.new('your-api-key')
  webhook_id = 23718
  sendlayer.webhooks.delete(webhook_id)
  ```

  ```go Go theme={null}
  sl := sendlayer.New("your-api-key")
  webhookID := 23718
  _ = sl.Webhooks.Delete(webhookID)
  ```

  ```bash cURL theme={null}
  curl --request DELETE \
    --url https://console.sendlayer.com/api/v1/webhooks/23718 \
    --header 'Authorization: Bearer <apiKey>'
  ```
</CodeGroup>

<Warning>Deleting a webhook cannot be undone. You won't be able to recover or access your webhook after deleting it.</Warning>

## Webhook Payload Format

When SendLayer sends a webhook notification to your endpoint, it includes detailed information about the event. Below, we've provided examples of the payload for each event:

<CodeGroup>
  ```json Open theme={null}
  {
    "event": {
      "method": "POST",
      "path": "/",
      "query": {},
      "client_ip": "0.0.0.0",
      "url": "https://your-domain.com/webhook",
      "headers": {
        "host": "your-domain.com",
        "content-length": 320,
        "user-agent": "GuzzleHttp/6.5.1 curl/7.68.0 PHP/5.6.40-67+ubuntu20.04.1+deb.sury.org+1",
        "content-type": "application/json"
      },
      "body": {
        "Signature": {
          "Timestamp": 1758100959,
          "Token": "c0a6c82bdde01faab7e857",
          "Signature": "3d1bf89405e4b71ed80bc240cd512aa7ed9db9dcfb17"
        },
        "EventData": {
          "Event": "opened",
          "Domain": "example.com",
          "MessageID": "4331c06-2d1d-4387-969e-697835",
          "To": "recipient@example.com",
          "IPAddress": "10.30.126.18"
        }
      }
    }
  }
  ```

  ```json Click theme={null}
  {
    "event": {
      "method": "POST",
      "path": "/",
      "query": {},
      "client_ip": "0.0.0.0",
      "url": "https://your-domain.com/webhook",
      "headers": {
        "host": "your-domain.com",
        "content-length": 320,
        "user-agent": "GuzzleHttp/6.5.1 curl/7.68.0 PHP/5.6.40-67+ubuntu20.04.1+deb.sury.org+1",
        "content-type": "application/json"
      },
      "body": {
        "Signature": {
          "Timestamp": 1758100959,
          "Token": "c0a6c82bdde01faab7e857",
          "Signature": "3d1bf89405e4b71ed80bc240cd512aa7ed9db9dcfb17"
        },
        "EventData": {
          "Event": "clicked",
          "Domain": "example.com",
          "MessageID": "4331c06-2d1d-4387-969e-697835",
          "To": "recipient@example.com",
          "IPAddress": "10.30.126.18"
        }
      }
    }
  }
  ```

  ```json Delivery theme={null}
  {
    "event": {
      "method": "POST",
      "path": "/",
      "query": {},
      "client_ip": "0.0.0.0",
      "url": "https://your-domain.com/webhook",
      "headers": {
        "host": "your-domain.com",
        "content-length": 320,
        "user-agent": "GuzzleHttp/6.5.1 curl/7.68.0 PHP/5.6.40-67+ubuntu20.04.1+deb.sury.org+1",
        "content-type": "application/json"
      },
      "body": {
        "Signature": {
          "Timestamp": 1758100959,
          "Token": "c0a6c82bdde01faab7e857",
          "Signature": "3d1bf89405e4b71ed80bc240cd512aa7ed9db9dcfb17"
        },
        "EventData": {
          "Event": "delivered",
          "Domain": "example.com",
          "MessageID": "4331c06-2d1d-4387-969e-697835",
          "To": "recipient@example.com",
        }
      }
    }
  }
  ```

  ```json Bounce theme={null}
  {
    "event": {
      "method": "POST",
      "path": "/",
      "query": {},
      "client_ip": "0.0.0.0",
      "url": "https://your-domain.com/webhook",
      "headers": {
        "host": "your-domain.com",
        "content-length": 320,
        "user-agent": "GuzzleHttp/6.5.1 curl/7.68.0 PHP/5.6.40-67+ubuntu20.04.1+deb.sury.org+1",
        "content-type": "application/json"
      },
      "body": {
        "Signature": {
          "Timestamp": 1758100959,
          "Token": "c0a6c82bdde01faab7e857",
          "Signature": "3d1bf89405e4b71ed80bc240cd512aa7ed9db9dcfb17"
        },
        "EventData": {
          "Event": "bounced",
          "EventType": "failed",
          "Domain": "example.com",
          "MessageID": "4331c06-2d1d-4387-969e-697835",
          "BouncedEmailAddress": {
            "EmailAddress": "recipient@example.com",
            "Status": "smtp;550 5.1.1 User Unknown",
            "DiagnosticCode": "5.1.1 (bad destination mailbox address)"
          },
          "Reason": "smtp;550 5.1.1 User Unknown",
          "Code": "5.1.1 (bad destination mailbox address)"
        }
      }
    }
  }
  ```

  ```json Unsubscribe theme={null}
  {
    "event": {
      "method": "POST",
      "path": "/",
      "query": {},
      "client_ip": "0.0.0.0",
      "url": "https://your-domain.com/webhook",
      "headers": {
        "host": "your-domain.com",
        "content-length": 320,
        "user-agent": "GuzzleHttp/6.5.1 curl/7.68.0 PHP/5.6.40-67+ubuntu20.04.1+deb.sury.org+1",
        "content-type": "application/json"
      },
      "body": {
        "Signature": {
          "Timestamp": 1758100959,
          "Token": "c0a6c82bdde01faab7e857",
          "Signature": "3d1bf89405e4b71ed80bc240cd512aa7ed9db9dcfb17"
        },
        "EventData": {
          "Event": "unsubscribed",
          "Domain": "example.com",
          "MessageID": "4331c06-2d1d-4387-969e-697835",
          "To": "recipient@example.com",
          "IPAddress": "10.30.126.18"
        }
      }
    }
  }
  ```
</CodeGroup>

## Best Practices

1. **Use HTTPs**: Always use HTTPs URLs for your webhook endpoints to ensure data security
2. **Monitor Status**: Regularly check your webhook status and response codes
3. **Error Handling**: Implement proper error handling for webhook processing

## FAQs

<AccordionGroup>
  <Accordion title="How many webhooks can I create?">
    You can create multiple webhooks for different events and endpoints. There's no strict limit, but it's recommended to keep the number manageable for easier maintenance.
  </Accordion>

  <Accordion title="What happens if my webhook endpoint is down?">
    SendLayer will retry sending webhook notifications if your endpoint is unavailable. Check the `LastResponseCode` and `LastResponseTryCounter` fields to monitor delivery status.
  </Accordion>

  <Accordion title="Can I update an existing webhook?">
    Currently, webhooks cannot be updated. You'll need to delete the existing webhook and create a new one with the updated configuration.
  </Accordion>

  <Accordion title="How do I test my webhook endpoint?">
    You can use tools like webhook.site or ngrok to create temporary public URLs for testing webhook functionality during development.
  </Accordion>

  <Accordion title="What should I do if webhooks stop working?">
    Check your webhook endpoint's availability, verify the URL is correct, and ensure your server can handle POST requests. Review the `LastResponseCode` field for error details.
  </Accordion>
</AccordionGroup>
