Documentation Index
Fetch the complete documentation index at: https://docs.tuco.ai/llms.txt
Use this file to discover all available pages before exploring further.
Webhooks
Tuco sends HTTP POST requests to your endpoint when message events occur. All payloads are signed with HMAC-SHA256.
Setup
- Go to API Keys → Webhooks tab
- Click Add Webhook
- Enter your endpoint URL
- Save the generated webhook secret
Events
| Event | Description |
|---|
message.sent | iMessage successfully delivered |
message.failed | Delivery failed (recipient may not have iMessage) |
message.fallback | iMessage unavailable — route to SMS provider |
message.reply | Lead replied to your message |
message.opened | Email message opened (email lines only) |
Payload Structure
{
"event": "message.reply",
"timestamp": "2026-04-15T12:00:00Z",
"workspaceId": "org_abc123",
"data": {
"messageId": "msg_xyz789",
"recipientPhone": "+19042956129",
"message": "Yes, I'm interested!",
"status": "received",
"lineId": "line_001",
"firstName": "Jane",
"lastName": "Smith",
"attachmentUrls": [],
"attachmentNames": []
}
}
| Header | Description |
|---|
X-Tuco-Signature | HMAC-SHA256 hex digest of the JSON body |
X-Tuco-Event | Event type (e.g., message.reply) |
X-Tuco-Timestamp | ISO 8601 timestamp |
Signature Verification
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(body))
.digest('hex');
return signature === expected;
}
Always verify the signature before processing webhook payloads. Reject requests with invalid signatures.
Testing
Click the Test button next to any webhook in the dashboard. Tuco sends a test payload with testMode: true and shows you the response status + latency.
Retry Policy
Tuco does not retry failed webhook deliveries. If your endpoint returns a non-2xx status, the event is logged but not resent. Use the Test button to verify your endpoint is reachable before going live.
Common Patterns
SMS Fallback
if (event === 'message.fallback') {
// Recipient doesn't have iMessage — send SMS via Twilio
await twilio.messages.create({
to: data.recipientPhone,
from: '+1YOURTWILIONUMBER',
body: data.message,
});
}
CRM Update
if (event === 'message.reply') {
// Update HubSpot contact with reply
await hubspot.crm.contacts.basicApi.update(contactId, {
properties: { last_reply: data.message, last_reply_date: data.timestamp }
});
}