Aller au contenu principal

Webhooks & Zapier Integration

ISAO API provides powerful webhook functionality for real-time notifications and seamless integration with automation platforms like Zapier, Make.com, and custom applications.

📋 Table of Contents​

🔔 Overview​

ISAO supports REST Hooks (reverse webhooks) that allow external applications to subscribe to real-time events. When events occur in your ISAO system, webhook notifications are sent automatically to your configured endpoints.

Supported Platforms​

  • Zapier: Connect 6000+ apps with automated workflows
  • Make.com: Advanced scenario automation
  • Custom Applications: Build your own integrations
  • n8n: Self-hosted automation alternative

Authentication​

All webhook endpoints require the webhooks:read or webhooks:write permissions:

Authorization: Bearer YOUR_API_KEY

⚡ Zapier Integration​

Quick Setup​

  1. Create a Zapier account at zapier.com
  2. Generate an API key with webhooks:write permission
  3. Create a Zap using ISAO as a trigger app
  4. Configure your action in another app

Zapier Trigger Setup​

// Example Zapier trigger configuration
const triggerConfig = {
"key": "new_contact",
"noun": "Contact",
"display": {
"label": "New Contact",
"description": "Triggers when a new contact is added to ISAO."
},
"operation": {
"type": "hook",
"performSubscribe": {
"url": "https://staging.isao.io/api/external/webhooks/subscribe",
"method": "POST",
"headers": {
"Authorization": "Bearer {{bundle.authData.api_key}}"
},
"body": {
"event": "contact.created",
"target_url": "{{bundle.targetUrl}}"
}
},
"performUnsubscribe": {
"url": "https://staging.isao.io/api/external/webhooks/unsubscribe",
"method": "DELETE",
"headers": {
"Authorization": "Bearer {{bundle.authData.api_key}}"
},
"body": {
"subscription_id": "{{bundle.subscribeData.subscription_id}}"
}
},
"performList": {
"url": "https://staging.isao.io/api/external/triggers/contact.created/recent",
"method": "GET",
"headers": {
"Authorization": "Bearer {{bundle.authData.api_key}}"
}
}
}
}

📡 Webhook Events​

Available Event Types​

EventDescriptionTrigger Condition
contact.createdNew contact addedWhen a contact is created via API or UI
contact.updatedContact information changedWhen contact data is modified
deal.createdNew deal addedWhen a deal is created
deal.updatedDeal information changedWhen deal data is modified
deal.stage_changedDeal moved to new stageWhen deal stage is updated
deal.wonDeal marked as wonWhen deal status changes to "won"
deal.lostDeal marked as lostWhen deal status changes to "lost"

Event Payload Structure​

All webhook events follow this structure:

{
"event": "contact.created",
"timestamp": "2024-11-08T10:30:00.000Z",
"data": {
// Event-specific data (contact, deal, etc.)
},
"metadata": {
"companyId": "cmb72clgt0003145mvfrg8iyh",
"eventId": "event_12345",
"source": "api"
}
}

🔗 REST Hooks​

Subscribe to Webhooks​

Create a new webhook subscription for real-time notifications.

Request​

POST /webhooks/subscribe
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

Body Parameters​

FieldTypeRequiredDescription
eventstring✅Event type to subscribe to
target_urlstring✅Your webhook endpoint URL
filtersobject❌Optional event filters

Example Request​

curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "contact.created",
"target_url": "https://hooks.zapier.com/hooks/catch/12345/abcdef",
"filters": {
"tags": ["lead", "enterprise"]
}
}' \
https://staging.isao.io/api/external/webhooks/subscribe

Response​

{
"success": true,
"data": {
"id": "hook_789",
"subscription_id": "sub_abc123",
"event": "contact.created",
"target_url": "https://hooks.zapier.com/hooks/catch/12345/abcdef",
"created_at": "2024-11-08T10:30:00.000Z"
}
}

Unsubscribe from Webhooks​

Remove an existing webhook subscription.

Request​

DELETE /webhooks/unsubscribe
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

Example Request​

curl -X DELETE \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subscription_id": "sub_abc123"
}' \
https://staging.isao.io/api/external/webhooks/unsubscribe

Response​

{
"success": true,
"message": "Webhook unsubscribed successfully"
}

List Active Webhooks​

Retrieve all active webhook subscriptions for your company.

Request​

GET /webhooks
Authorization: Bearer YOUR_API_KEY

Example Request​

curl -H "Authorization: Bearer YOUR_API_KEY" \
https://staging.isao.io/api/external/webhooks

Response​

{
"success": true,
"data": [
{
"id": "hook_789",
"subscription_id": "sub_abc123",
"event_type": "contact.created",
"target_url": "https://hooks.zapier.com/hooks/catch/12345/abcdef",
"is_active": true,
"created_at": "2024-11-08T10:30:00.000Z"
}
]
}

📄 Event Samples​

Get Sample Data​

Retrieve sample event data for testing and development.

Request​

GET /triggers/:event_type/sample
Authorization: Bearer YOUR_API_KEY

Example Request​

curl -H "Authorization: Bearer YOUR_API_KEY" \
https://staging.isao.io/api/external/triggers/contact.created/sample

Response​

{
"id": "contact_sample",
"name": "John Doe",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+33123456789",
"email": "john.doe@example.com",
"position": "CEO",
"currentCompany": "Tech Corp",
"industrySector": "Technology",
"city": "Paris",
"country": "France",
"tags": ["vip", "enterprise"],
"createdAt": "2024-11-08T10:30:00.000Z",
"updatedAt": "2024-11-08T10:30:00.000Z"
}

Get Recent Data​

Retrieve recent real data for polling-based integrations.

Request​

GET /triggers/:event_type/recent?limit=100&since=2024-11-01T00:00:00.000Z
Authorization: Bearer YOUR_API_KEY

Example Request​

curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://staging.isao.io/api/external/triggers/contact.created/recent?limit=10"

Response​

[
{
"id": "contact_123",
"name": "Jane Smith",
"firstName": "Jane",
"lastName": "Smith",
"phoneNumber": "+33987654321",
"email": "jane@example.com",
"createdAt": "2024-11-08T09:30:00.000Z",
"updatedAt": "2024-11-08T09:30:00.000Z"
}
]

🔧 Zapier App Development​

Authentication Configuration​

// authentication.js
module.exports = {
type: 'custom',
fields: [
{
computed: false,
key: 'api_key',
required: true,
label: 'API Key',
type: 'password',
helpText: 'Your ISAO API key from the dashboard'
}
],
test: {
url: 'https://staging.isao.io/api/external/test',
method: 'GET',
headers: {
'Authorization': 'Bearer {{bundle.authData.api_key}}'
}
},
connectionLabel: 'Connected to ISAO ({{bundle.authData.company_name}})'
};

Trigger Definition​

// triggers/new_contact.js
const perform = (z, bundle) => {
// Return recent contacts for initial poll
const options = {
url: 'https://staging.isao.io/api/external/triggers/contact.created/recent',
method: 'GET',
headers: {
'Authorization': `Bearer ${bundle.authData.api_key}`
},
params: {
limit: bundle.meta.limit || 100
}
};

return z.request(options).then((response) => {
return response.json;
});
};

const performSubscribe = (z, bundle) => {
// Subscribe to webhook
const options = {
url: 'https://staging.isao.io/api/external/webhooks/subscribe',
method: 'POST',
headers: {
'Authorization': `Bearer ${bundle.authData.api_key}`,
'Content-Type': 'application/json'
},
body: {
event: 'contact.created',
target_url: bundle.targetUrl
}
};

return z.request(options).then((response) => {
return response.json.data;
});
};

const performUnsubscribe = (z, bundle) => {
// Unsubscribe from webhook
const options = {
url: 'https://staging.isao.io/api/external/webhooks/unsubscribe',
method: 'DELETE',
headers: {
'Authorization': `Bearer ${bundle.authData.api_key}`,
'Content-Type': 'application/json'
},
body: {
subscription_id: bundle.subscribeData.subscription_id
}
};

return z.request(options);
};

module.exports = {
key: 'new_contact',
noun: 'Contact',
display: {
label: 'New Contact',
description: 'Triggers when a new contact is added to ISAO.'
},
operation: {
type: 'hook',
performSubscribe,
performUnsubscribe,
perform,
sample: {
id: 'contact_123',
name: 'John Doe',
email: 'john@example.com',
phoneNumber: '+33123456789'
}
}
};

Action Definition​

// creates/create_contact.js
const perform = (z, bundle) => {
const options = {
url: 'https://staging.isao.io/api/external/contacts',
method: 'POST',
headers: {
'Authorization': `Bearer ${bundle.authData.api_key}`,
'Content-Type': 'application/json'
},
body: {
name: bundle.inputData.name,
phoneNumber: bundle.inputData.phoneNumber,
email: bundle.inputData.email,
position: bundle.inputData.position,
currentCompany: bundle.inputData.currentCompany,
tags: bundle.inputData.tags ? bundle.inputData.tags.split(',') : []
}
};

return z.request(options).then((response) => {
return response.json.data;
});
};

module.exports = {
key: 'create_contact',
noun: 'Contact',
display: {
label: 'Create Contact',
description: 'Creates a new contact in ISAO.'
},
operation: {
inputFields: [
{
key: 'name',
label: 'Name',
type: 'string',
required: true
},
{
key: 'phoneNumber',
label: 'Phone Number',
type: 'string',
required: true
},
{
key: 'email',
label: 'Email',
type: 'string',
required: false
},
{
key: 'position',
label: 'Position',
type: 'string',
required: false
},
{
key: 'currentCompany',
label: 'Company',
type: 'string',
required: false
},
{
key: 'tags',
label: 'Tags',
type: 'string',
helpText: 'Comma-separated list of tags',
required: false
}
],
perform,
sample: {
id: 'contact_123',
name: 'John Doe',
email: 'john@example.com'
}
}
};

🔄 Make.com Integration​

HTTP Module Configuration​

{
"url": "https://staging.isao.io/api/external/contacts",
"method": "POST",
"headers": {
"Authorization": "Bearer {{your_api_key}}",
"Content-Type": "application/json"
},
"body": {
"name": "{{contact.name}}",
"phoneNumber": "{{contact.phone}}",
"email": "{{contact.email}}"
}
}

Webhook Module Setup​

  1. Add Webhook trigger in your Make scenario
  2. Copy the webhook URL provided by Make
  3. Subscribe to ISAO events using the webhook URL:
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "contact.created",
"target_url": "https://hook.eu1.make.com/12345abcdef"
}' \
https://staging.isao.io/api/external/webhooks/subscribe

🛠️ Custom Webhooks​

Node.js Webhook Receiver​

const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

// Webhook endpoint
app.post('/webhook/isao', (req, res) => {
const event = req.body;

console.log('Received event:', event.event);
console.log('Event data:', event.data);

// Process the event based on type
switch (event.event) {
case 'contact.created':
handleNewContact(event.data);
break;
case 'deal.won':
handleDealWon(event.data);
break;
default:
console.log('Unknown event type:', event.event);
}

// Respond with 200 to acknowledge receipt
res.status(200).json({ received: true });
});

function handleNewContact(contact) {
console.log('New contact:', contact.name);
// Add your business logic here
// e.g., send welcome email, add to CRM, etc.
}

function handleDealWon(deal) {
console.log('Deal won:', deal.title, deal.value);
// Add your business logic here
// e.g., generate invoice, send congratulations, etc.
}

app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});

Python Flask Webhook Receiver​

from flask import Flask, request, jsonify
import logging

app = Flask(__name__)
logging.basicConfig(level=logging.INFO)

@app.route('/webhook/isao', methods=['POST'])
def handle_webhook():
event_data = request.json
event_type = event_data.get('event')
data = event_data.get('data', {})

logging.info(f"Received event: {event_type}")

if event_type == 'contact.created':
handle_new_contact(data)
elif event_type == 'deal.won':
handle_deal_won(data)
else:
logging.warning(f"Unknown event type: {event_type}")

return jsonify({'received': True}), 200

def handle_new_contact(contact):
logging.info(f"New contact: {contact.get('name')}")
# Add your business logic here

def handle_deal_won(deal):
logging.info(f"Deal won: {deal.get('title')} - {deal.get('value')}")
# Add your business logic here

if __name__ == '__main__':
app.run(debug=True, port=3000)

🔍 Troubleshooting​

Common Issues​

1. Webhook Not Receiving Events​

Check:

  • Webhook URL is publicly accessible (use ngrok for local testing)
  • API key has webhooks:write permission
  • Subscription is active (check with GET /webhooks)
  • Webhook endpoint responds with 200 status

Debug:

# Test webhook endpoint manually
curl -X POST \
-H "Content-Type: application/json" \
-d '{"event":"test","data":{"test":true}}' \
https://your-webhook-url.com/webhook

2. Zapier Trigger Not Working​

Check:

  • API key is correctly entered in Zapier
  • Trigger is properly subscribed
  • Sample data is available

Debug:

# Check recent trigger data
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://staging.isao.io/api/external/triggers/contact.created/recent?limit=1"

3. Event Payload Issues​

Common problems:

  • Missing required fields in webhook payload
  • Incorrect date format expectations
  • Nested object access in automation tools

Solution: Use the sample endpoints to understand exact payload structure:

curl -H "Authorization: Bearer YOUR_API_KEY" \
https://staging.isao.io/api/external/triggers/contact.created/sample

Testing Webhooks Locally​

Using ngrok​

  1. Install ngrok: ngrok.com
  2. Start your local server on port 3000
  3. Expose with ngrok:
    ngrok http 3000
  4. Use the ngrok URL for webhook subscription:
    curl -X POST \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "event": "contact.created",
    "target_url": "https://abc123.ngrok.io/webhook/isao"
    }' \
    https://staging.isao.io/api/external/webhooks/subscribe

Webhook Testing Tools​

Event Delivery Guarantees​

  • Retry Policy: Failed webhooks are retried up to 3 times
  • Timeout: Webhooks timeout after 30 seconds
  • Order: Events are delivered in the order they occur
  • Deduplication: Each event has a unique eventId for deduplication

📈 Best Practices​

  1. Respond quickly: Always respond with 200 status within 30 seconds
  2. Handle duplicates: Use eventId for idempotent processing
  3. Verify signatures: Implement signature verification for security
  4. Use HTTPS: Always use HTTPS endpoints for webhooks
  5. Log events: Keep logs of received events for debugging
  6. Graceful degradation: Handle missing or unexpected fields
  7. Test thoroughly: Use sample data to test your integration
  8. Monitor health: Set up alerts for webhook failures