ZooTools is now SMASHSENDRead update

Webhooks API

The Webhooks API allows you to receive real-time notifications about events in your SMASHSEND account. You can create webhooks to receive notifications for various events, such as when a new contact is created, when a campaign is sent, or when a user opens an email.

Webhooks send HTTP POST requests to your specified URL when events happen in your SMASHSEND account.

Events

Webhooks can be configured to listen for the following events:

  • CONTACT_CREATED - A new contact was created
  • CONTACT_UPDATED - A contact was updated
  • CONTACT_UNSUBSCRIBED - A contact has unsubscribed
  • CONTACT_RESUBSCRIBED - A contact has resubscribed
  • CONTACT_DELETED - A contact was deleted
  • WORKSPACE_TEAM_MEMBER_JOINED - A team member joined the workspace

Endpoints

GET/v1/webhooks

Lists all webhooks for the authenticated workspace.

Authentication

Requires a valid API key with api_user scope.

Request

curl https://api.smashsend.com/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "webhooks": [
    {
      "id": "wh_123456789",
      "url": "https://example.com/webhooks/zootools",
      "events": ["contact.created", "contact.updated"],
      "createdAt": "2023-03-01T10:00:00Z"
    },
    {
      "id": "wh_987654321",
      "url": "https://example.com/webhooks/zootools-campaigns",
      "events": ["campaign.sent", "campaign.opened", "campaign.clicked"],
      "createdAt": "2023-04-10T14:30:00Z"
    }
  ]
}

GET/v1/webhooks/{webhookId}

Retrieves details of a specific webhook.

Authentication

Requires a valid API key with user scope.

Path Parameters

webhookId - The ID of the webhook to retrieve

Request

curl https://api.smashsend.com/v1/webhooks/wh_123456789 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "webhook": {
    "id": "wh_123456789",
    "url": "https://example.com/webhooks/zootools",
    "events": ["contact.created", "contact.updated"],
    "token": "wht_a1b2c3d4e5f6g7h8i9j0",
    "createdAt": "2023-03-01T10:00:00Z"
  }
}

POST/v1/webhooks

Creates a new webhook.

Authentication

Requires a valid API key with api_user scope.

Request Body

{
  "url": "https://example.com/webhooks/zootools",
  "events": ["CONTACT_CREATED", "CONTACT_UPDATED"],
  "token": "optional_secret_token"
}

Request

curl -X POST https://api.smashsend.com/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/zootools",
    "events": ["CONTACT_CREATED", "CONTACT_UPDATED"],
    "token": "optional_secret_token"
  }'

Response

{
  "webhook": {
    "id": "wh_123456789",
    "url": "https://example.com/webhooks/zootools",
    "events": ["CONTACT_CREATED", "CONTACT_UPDATED"],
    "token": "wht_a1b2c3d4e5f6g7h8i9j0",
    "createdAt": "2023-04-16T15:45:00Z"
  }
}

PUT/v1/webhooks/{webhookId}

Updates a webhook.

Authentication

Requires a valid API key with user scope.

Path Parameters

webhookId - The ID of the webhook to update

Request Body

{
  "events": ["CONTACT_CREATED", "CONTACT_UPDATED", "WORKSPACE_TEAM_MEMBER_JOINED"]
}

Request

curl -X PUT https://api.smashsend.com/v1/webhooks/wh_123456789 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["CONTACT_CREATED", "CONTACT_UPDATED", "WORKSPACE_TEAM_MEMBER_JOINED"]
  }'

Response

{
  "webhook": {
    "id": "wh_123456789",
    "url": "https://example.com/webhooks/zootools",
    "events": ["CONTACT_CREATED", "CONTACT_UPDATED", "WORKSPACE_TEAM_MEMBER_JOINED"],
    "token": "wht_a1b2c3d4e5f6g7h8i9j0",
    "createdAt": "2023-03-01T10:00:00Z"
  }
}

DELETE/v1/webhooks/{webhookId}

Deletes a webhook.

Authentication

Requires a valid API key with user scope.

Path Parameters

webhookId - The ID of the webhook to delete

Request

curl -X DELETE https://api.smashsend.com/v1/webhooks/wh_123456789 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "deleted": true
}

Webhook Payloads

When an event occurs, SMASHSEND will send a POST request to your webhook URL with a JSON payload. The payload will contain information about the event, including the event type and the data related to the event.

Example Payload for CONTACT_CREATED event:

{
  "event": "CONTACT_CREATED",
  "created_at": "2023-04-16T15:45:00Z",
  "data": {
    "contact": {
      "id": "cont_123456789",
      "email": "newcontact@example.com",
      "name": "New Contact",
      "createdAt": "2023-04-16T15:45:00Z"
    }
  }
}

Example Payload for WORKSPACE_TEAM_MEMBER_JOINED event:

{
  "event": "WORKSPACE_TEAM_MEMBER_JOINED",
  "created_at": "2023-04-16T16:30:00Z",
  "data": {
    "workspace": {
      "id": "wksp_123456789",
      "name": "My Workspace"
    },
    "user": {
      "id": "usr_987654321",
      "email": "teammember@example.com",
      "name": "Team Member"
    }
  }
}

Webhook Security

To verify that the webhook request is coming from SMASHSEND, you can check the X-SMASHSEND-Signature header. This header contains a signature generated using your webhook token and the request payload.

To verify the signature:

  1. Get the X-SMASHSEND-Signature header value from the request
  2. Compute an HMAC using your webhook token as the key and the request body as the message
  3. Compare the computed HMAC with the signature in the header

Example in Node.js:

const crypto = require('crypto');

function verifyWebhookSignature(body, signature, token) {
  const hmac = crypto.createHmac('sha256', token);
  const computedSignature = hmac.update(body).digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(computedSignature)
  );
}

// In your webhook handler
app.post('/webhooks/zootools', (req, res) => {
  const signature = req.headers['x-zootools-signature'];
  const body = JSON.stringify(req.body);
  const token = 'YOUR_WEBHOOK_TOKEN';
  
  if (verifyWebhookSignature(body, signature, token)) {
    // Process the webhook event
    console.log('Webhook signature verified!');
    // Handle the event based on req.body.event
    res.status(200).send('Webhook received');
  } else {
    console.log('Webhook signature verification failed!');
    res.status(401).send('Unauthorized');
  }
});