# Webhook Setup Guide — Real-Time iMessage Events

*By Bharadwaj Giridhar · Published 2026-04-15*

**Canonical URL:** https://tuco.ai/blog/tuco-webhook-setup-guide-real-time-imessage-events
**Tags:** developers, webhooks, integrations, api

## Summary

Set up Tuco webhooks to receive real-time notifications when messages are sent, delivered, failed, or replied to.

---


# Webhook Setup Guide — Real-Time iMessage Events for Your Stack

Webhooks let you react to iMessage events in real time. When a message is sent, a lead replies, or a delivery fails, Tuco sends a signed POST request to your endpoint.

## Supported Events

| Event | When It Fires |
|-------|--------------|
| `message.sent` | iMessage successfully delivered |
| `message.failed` | Delivery failed (recipient may not have iMessage) |
| `message.fallback` | iMessage unavailable — route to your SMS provider |
| `message.reply` | Lead replied to your message |
| `message.opened` | Email message was opened (email lines only) |

## Setting Up a Webhook

1. Go to **API Keys** → **Webhooks** tab in your dashboard
2. Click **Add Webhook**
3. Enter your endpoint URL (e.g., `https://your-app.com/api/tuco-webhook`)
4. Copy the generated webhook secret — you'll need it to verify signatures

## Verifying Signatures

Every webhook payload is signed with HMAC-SHA256 using your webhook secret. Always verify the signature before processing:

```javascript
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(body))
    .digest('hex');
  return signature === expected;
}

// In your handler:
app.post('/api/tuco-webhook', (req, res) => {
  const sig = req.headers['x-tuco-signature'];
  if (!verifyWebhook(req.body, sig, process.env.TUCO_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const { event, data } = req.body;
  
  switch (event) {
    case 'message.reply':
      // Lead replied — update your CRM, notify your team
      console.log(`Reply from ${data.recipientPhone}: ${data.message}`);
      break;
    case 'message.fallback':
      // iMessage unavailable — trigger SMS via Twilio/MessageBird
      sendSMS(data.recipientPhone, data.message);
      break;
  }
  
  res.status(200).send('ok');
});
```

## Testing Your Webhook

Click the **Test** button next to any webhook in the dashboard. Tuco sends a test payload (with `testMode: true`) to your endpoint and shows you the response status code and latency.

The test payload has the same structure and HMAC signature as real events — use it to verify your endpoint works before going live.

## Payload Structure

```json
{
  "event": "message.reply",
  "timestamp": "2026-04-15T12:00:00Z",
  "workspaceId": "org_abc123",
  "data": {
    "messageId": "msg_xyz789",
    "recipientPhone": "+19042956129",
    "message": "Yes, I'm interested! Can you tell me more?",
    "status": "received",
    "lineId": "line_001",
    "firstName": "Jane",
    "lastName": "Smith",
    "attachmentUrls": [],
    "attachmentNames": []
  }
}
```

## Headers

| Header | Value |
|--------|-------|
| `X-Tuco-Signature` | HMAC-SHA256 hex digest |
| `X-Tuco-Event` | Event type (e.g., `message.reply`) |
| `X-Tuco-Timestamp` | ISO 8601 timestamp |
| `Content-Type` | `application/json` |

## Common Use Cases

- **SMS Fallback**: On `message.fallback`, trigger your SMS provider (Twilio, MessageBird) for non-iPhone contacts
- **CRM Updates**: On `message.reply`, update the contact record in HubSpot or Salesforce
- **Team Alerts**: On `message.reply`, post to Slack or email the account owner
- **Analytics**: Track delivery rates, reply rates, and fallback percentages

---

*Webhooks are available on all Tuco plans. [Set up your first webhook](https://app.tuco.ai/api-keys) or [book a demo](/demo).*
