🔗 Live Integration

Real-Time iMessage Events

HMAC-signed webhooks for every iMessage lifecycle event. Build real-time workflows, sync your CRM, and react to replies instantly.

5 Event Types

Cover every stage of the iMessage lifecycle.

📤

message.sent

Fires when an iMessage is successfully sent (accepted by Tuco)

message.failed

Fires when sending fails after all retries — technical error, reason included

🛟

message.fallback

Fires when the recipient has no iMessage — route the text to your SMS provider

💬

message.reply

Fires when the recipient replies — reply text and conversation history included

❤️

message.reaction

Fires when the recipient reacts (tapback) to a message you sent

👁️

message.opened

Fires on iMessage read receipts (when enabled by the recipient) or email opens

🤖

message.ai_draft

Fires when the AI copilot drafts a reply for review — approve or reject via the API

message.ai_draft_approved

Fires when a draft is approved and sent, from any channel — dashboard, Telegram, or API

🚫

message.ai_draft_rejected

Fires when a draft is rejected from any channel

HMAC Signature Verification

Every webhook includes an x-tuco-signature header. Verify it to ensure authenticity.

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-tuco-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.TUCO_WEBHOOK_SECRET
  );

  if (!isValid) return res.status(401).send('Invalid signature');

  // Process the event
  const { event, data } = req.body;
  console.log(`Received ${event}`, data);
  res.status(200).send('OK');
});

Payload Structure

Every event follows a consistent JSON structure.

{
  "event": "message.reply",
  "timestamp": "2026-04-15T10:30:00Z",
  "data": {
    "message_id": "msg_abc123",
    "from": "+15550100200",
    "to": "+15550123456",
    "body": "Sure, I'm interested. When can we talk?",
    "line_id": "line_xyz789",
    "campaign_id": "camp_def456"
  }
}

Ready to Build with Webhooks?

Set up your webhook endpoint and start receiving events in minutes.

Get StartedStarter self-serve, Growth demos