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
eventstringEvent type to subscribe to
target_urlstringYour webhook endpoint URL
filtersobjectOptional 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