Webhook integration

IN THIS ARTICLE

The Webhooks integration allows automations to send event data to custom endpoints using the Send Webhook action.

What are webhooks?

Webhooks are a way for Estii to send real-time data to external systems when events occur. Unlike traditional integrations that require platform-specific setup, webhooks allow you to send event data to any HTTPS endpoint you control.

This makes webhooks ideal for:

  • Building custom integrations with internal tools
  • Connecting to automation platforms like n8n, Make.com, or Zapier
  • Triggering workflows in systems that support webhook receivers
  • Integrating with platforms not yet directly supported by Estii

Setting up webhook automations

Webhooks don't require any connection setup in the Integrations tab. You can start using them immediately by creating an automation with a Send Webhook action.

Creating a webhook automation

  1. Go to Settings > Workflow > Automations
  2. Click "Create Automation" or use a template
  3. Select an event to trigger the automation (e.g., "Deal Updated")
  4. Add conditions if needed to filter when the webhook fires
  5. Add a "Send Webhook" action
  6. Configure the webhook URL, secret, and optional message

Webhook action configuration
Webhook action configuration
Send webhook event
Send webhook event

Webhook configuration

When you add a Send Webhook action, you'll need to configure the following fields:

Webhook URL (required)

The HTTPS endpoint where Estii will send the webhook payload. This must be a valid HTTPS URL (except for localhost/127.0.0.1 which is allowed for development).

Example: https://hooks.example.com/estii-events or http://localhost:3000/webhook

Message (optional)

An optional custom message that will be included in the webhook payload. This field supports dynamic values from the triggering event using the $field syntax.

Example: Deal $name status changed to $status

Webhook payload

All webhooks send a JSON payload with the following structure:

{
  "event": "estii_deal_updated",
  "space_id": "abc123",
  "timestamp": "2026-01-27T14:30:00.000Z",
  "deal": {
    "id": "xyz789",
    "url": "https://app.estii.com/abc123/deals/xyz789",
    "name": "Acme Project",
    "status": "approved",
    "price": 55000,
    "cost": 40000,
    "currency": "usd",
    "margin": 0.27,
    "start": "2026-02-01T00:00:00.000Z",
    "end": "2026-03-15T00:00:00.000Z",
    "due": "2026-01-31T00:00:00.000Z",
    "owner": {
      "id": "member_456",
      "name": "Dom"
    }
  },
  "changes": {
    "status": "draft"
  },
  "message": "Deal Acme Project approved"
}

Payload fields

FieldTypeDescription
eventstringThe type of event that triggered the webhook (e.g., "estii_deal_updated")
space_idstringThe ID of the space where the event occurred
timestampstringISO 8601 timestamp of when the event occurred
dealobjectCurrent state of the deal (see Deal fields below)
changesobjectPrevious values of fields that changed (empty if no tracked fields changed)
messagestringYour custom message (if configured)

Deal fields

The deal object contains the current state of all tracked deal fields:

FieldTypeDescription
idstringThe ID of the deal
urlstringDirect link to the deal in Estii
namestringDeal name
statusstringDeal status (draft/approved/won/lost/abandoned)
pricenumberDeal price in space currency (rounded to 2 decimal places)
costnumberDeal cost in space currency (rounded to 2 decimal places)
currencystringDeal currency code (e.g., "usd", "gbp")
marginnumberDeal margin (0-1, rounded to 4 decimal places)
target_pricenumberTarget price (rounded to 2 decimal places)
probabilitynumberWin probability (0-1, rounded to 4 decimal places)
startstringEstimated start date (ISO 8601 timestamp)
endstringEstimated end date (ISO 8601 timestamp)
duestringDue date (ISO 8601 timestamp)
descriptionstringDeal description
ownerobject (optional)Deal owner information (only present if deal has an owner)
owner.idstringThe member ID of the deal owner
owner.namestringThe display name of the deal owner

Changes object

The changes object contains the previous values of fields that changed. This allows you to:

  • See what changed by checking which keys are present
  • Know the previous value for each changed field
  • Detect the nature of the change by comparing with current values in deal

Example when status changed from "draft" to "approved":

"changes": {
  "status": "draft"
}

If no tracked fields changed, changes will be an empty object: {}

Verifying webhook requests

Every webhook request includes an X-Estii-Webhook header containing the secret you configured. Your receiving endpoint should verify this header matches your stored secret before processing the payload.

Example verification (Node.js):

app.post('/estii-webhook', (req, res) => {
  const receivedSecret = req.headers['x-estii-webhook'];
  const expectedSecret = process.env.ESTII_WEBHOOK_SECRET;
  
  if (receivedSecret !== expectedSecret) {
    return res.status(401).json({ error: 'Invalid secret' });
  }
  
  // Process the webhook payload
  const { event, space_id, deal, changes } = req.body;
  console.log(`Received ${event} for deal ${deal.id}`);
  
  // Check what changed
  if (changes.status) {
    console.log(`Status changed from ${changes.status} to ${deal.status}`);
  }
  
  res.status(200).json({ success: true });
});

Testing webhooks

Use the "Send Test" button in the webhook action configuration to send a sample payload to your endpoint. This helps verify your endpoint is correctly configured before the automation goes live.

The test payload uses realistic dummy data:

{
  "event": "deal_updated",
  "space_id": "test_space",
  "timestamp": "2026-01-27T12:00:00.000Z",
  "deal": {
    "id": "test_deal",
    "url": "https://app.estii.com/test_space/deals/test_deal",
    "name": "Sample Deal",
    "status": "approved",
    "price": 10000,
    "owner": { "id": "test_user", "name": "Test User" }
  },
  "changes": {},
  "message": "Test message from Estii"
}

Delivery and retries

Estii attempts to deliver webhooks with the following retry logic:

  1. Initial attempt: Immediate delivery
  2. First retry: After 1 second (if initial attempt fails)
  3. Second retry: After 5 seconds (if first retry fails)
  4. Final retry: After 30 seconds (if second retry fails)

A delivery is considered successful if your endpoint returns a 2xx HTTP status code.

Important notes:

  • 4xx responses (client errors) are not retried, as they typically indicate a configuration issue
  • 5xx responses (server errors) and network failures trigger retries
  • Failed deliveries don't block the automation from completing

Example integrations

n8n

  1. In n8n, create a new workflow with a Webhook trigger node
  2. Set the webhook to accept POST requests
  3. Copy the webhook URL from n8n
  4. In Estii, create a webhook automation and paste the URL
  5. Copy the secret from Estii and add header verification in n8n

Make.com

  1. In Make.com, create a new scenario with a Webhooks module
  2. Choose "Custom webhook" and create a new webhook
  3. Copy the webhook URL
  4. In Estii, create a webhook automation and paste the URL
  5. Use the secret in Make.com to verify incoming requests

Custom endpoint

Any HTTPS endpoint that can receive POST requests with JSON payloads can receive Estii webhooks. Ensure your endpoint:

  • Accepts POST requests with Content-Type: application/json
  • Verifies the X-Estii-Webhook header matches your stored secret
  • Returns a 2xx status code for successful processing
  • Responds within a reasonable timeout (under 30 seconds)

Need help?

Don't hesitate to get in touch with our support team if you require further assistance on using webhook automations.