Platform

Webhooks & events

Get called when something happens — deal won, contact replied, quote accepted, task overdue… — with signed, retried deliveries; plus REST hooks for Zapier, n8n and Make, and the event log.

Every change in Meetzy is an event (the full list is in the reference). A webhook subscribes a URL to events — exact types, a whole family (deal.*) or everything (*). Webhook endpoints need a key with the webhooks scope.

In a chat
Copy a ready promptPaste it in any AI: it reads the docs and follows the rules of the API.
Open in Claude or ChatGPTA new conversation with the prompt already written.
This page as MarkdownFor an AI that cannot open links: paste the text itself.
In your editor
Claude Code or CodexAdd this line to CLAUDE.md or AGENTS.md.Meetzy API reference (read before calling the API): https://www.meetzy.ai/llms-full.txt
CursorSettings › Indexing & Docs › Add Doc, then type @Meetzy in the chat.https://www.meetzy.ai/llms-full.txt
Connect Meetzy as tools (MCP)The AI can then read and change your CRM itself — Claude Code:claude mcp add --transport http meetzy https://meetzy.me/api/mcp/mcp
Same for Codexcodex mcp add meetzy --url https://meetzy.me/api/mcp/mcp
GET/webhooks

List webhooks

Every webhook with its URL, events, whether it is active, the last status code and delivery time, and consecutive failures.

Scope: webhooks
Request
curl "https://meetzy.me/api/v1/webhooks" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/webhooks", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/webhooks",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "webhooks": [
    {
      "id": "c39ea9df-9ff5-4345-af78-cfd7161a310e",
      "user_from": "acme",
      "url": "https://hooks.acme.com/meetzy",
      "events": [
        "deal.won"
      ],
      "secret": "whsec_8f3c…",
      "description": null,
      "source": "api",
      "active": true,
      "failure_count": 0,
      "last_status": null,
      "last_delivery_at": null,
      "created_by": "olivia@acme.com",
      "created_at": "2026-10-07T13:23:46.551452+00:00"
    },
    {
      "id": "03010268-da43-436e-a917-0eafb2bcfe57",
      "user_from": "acme",
      "url": "https://hooks.zapier.com/hooks/standard/123/abc",
      "events": [
        "contact.created"
      ],
      "secret": "whsec_8f3c…",
      "description": "REST hook",
      "source": "rest_hook",
      "active": true,
      "failure_count": 4,
      "last_status": 405,
      "last_delivery_at": "2026-10-07T13:22:39.73+00:00",
      "created_by": "olivia@acme.com",
      "created_at": "2026-10-07T13:09:54.218681+00:00"
    }
  ]
}
POST/webhooks

Create a webhook

The answer contains the secret used to sign deliveries — store it. The URL must be https. Send a test with POST /webhooks/{id}/test.

Scope: webhooks

Body

urlstringrequired
Your endpoint (https://…).
eventsstring[]
Event types, family.*, or ["*"] (default).
descriptionstring
What it is for.
secretstring
Your own signing secret (default: generated).
Request
curl -X POST "https://meetzy.me/api/v1/webhooks" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.acme.com/meetzy",
    "events": [
      "deal.won",
      "quote.accepted",
      "contact.*"
    ],
    "description": "ERP order creation"
  }'
const res = await fetch("https://meetzy.me/api/v1/webhooks", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "url": "https://hooks.acme.com/meetzy",
    "events": [
      "deal.won",
      "quote.accepted",
      "contact.*"
    ],
    "description": "ERP order creation"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/webhooks",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "url": "https://hooks.acme.com/meetzy",
        "events": ["deal.won", "quote.accepted", "contact.*"],
        "description": "ERP order creation"
    },
)
data = res.json()
Response201
{
  "id": "c39ea9df-9ff5-4345-af78-cfd7161a310e",
  "user_from": "acme",
  "url": "https://hooks.acme.com/meetzy",
  "events": [
    "deal.won"
  ],
  "secret": "whsec_8f3c…",
  "description": null,
  "source": "api",
  "active": true,
  "failure_count": 0,
  "last_status": null,
  "last_delivery_at": null,
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:46.551452+00:00"
}
PATCH/webhooks/{id}

Update a webhook

Change the URL, the events, the description, or switch it on and off. Re-activating resets the failure counter.

Scope: webhooks

Path parameters

idstringrequired
Id of the record (UUID).

Body

urlstring
Endpoint.
eventsstring[]
Events.
descriptionstring
Description.
activeboolean
On or off.

Returns the webhook.

Request
curl -X PATCH "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "active": true
  }'
const res = await fetch("https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "active": true
  }),
});
const data = await res.json();
import os, requests

res = requests.patch(
    "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "active": True
    },
)
data = res.json()
Response200

See the notes on the left.

DELETE/webhooks/{id}

Delete a webhook

Scope: webhooks

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X DELETE "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "deleted": true
}
POST/webhooks/{id}/test

Send a test delivery

Sends a sample payload ("test": true) now and returns what your endpoint answered. Tests are not retried.

Scope: webhooks

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X POST "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/test" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/test", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/test",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "ok": true,
  "status": 200,
  "duration_ms": 182,
  "response": "ok",
  "attempt": 1,
  "next_retry_at": null
}
GET/webhooks/{id}/deliveries

Delivery log

The latest deliveries: event, status code, duration, your response (first 500 characters), attempt number and next retry.

Scope: webhooks

Path parameters

idstringrequired
Id of the record (UUID).

Up to the last 50 deliveries.

Request
curl "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/deliveries" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/deliveries", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/deliveries",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "deliveries": [
    {
      "id": "f1e2d3c4-b5a6-4789-8a7b-6c5d4e3f2a1b",
      "webhook_id": "4f8e2b1a-9c3d-4e5f-8a7b-6c5d4e3f2a10",
      "event_id": 3307,
      "event_type": "deal.won",
      "status_code": 200,
      "ok": true,
      "duration_ms": 214,
      "response": "ok",
      "payload": {
        "id": "evt_3307",
        "type": "deal.won",
        "created_at": "2026-10-07T10:02:10Z",
        "organization": "acme",
        "entity": {
          "type": "deal",
          "id": "5eecc043-d70d-4b94-a604-7e1a35d92edf"
        },
        "data": {
          "record": {
            "id": "5eecc043-d70d-4b94-a604-7e1a35d92edf",
            "name": "Payfit — rollout",
            "amount": 12000,
            "status": "won"
          }
        },
        "test": false
      },
      "attempt": 1,
      "next_retry_at": null,
      "created_at": "2026-10-07T10:02:11Z"
    }
  ]
}
POST/webhooks/{id}/deliveries/{deliveryId}/redeliver

Resend a delivery

Sends the same payload again (same delivery id, next attempt number).

Scope: webhooks

Path parameters

idstringrequired
Id of the record (UUID).
deliveryIdstringrequired
Id of the delivery (from the delivery log).
Request
curl -X POST "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/deliveries/f1e2d3c4-b5a6-4789-8a7b-6c5d4e3f2a1b/redeliver" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/deliveries/f1e2d3c4-b5a6-4789-8a7b-6c5d4e3f2a1b/redeliver", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/webhooks/e43414d6-f56f-42be-a64c-a836d6015efc/deliveries/f1e2d3c4-b5a6-4789-8a7b-6c5d4e3f2a1b/redeliver",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "ok": true,
  "status": 200,
  "duration_ms": 160,
  "response": "ok",
  "attempt": 2,
  "next_retry_at": null
}
POST/hooks

Subscribe a REST hook (Zapier, n8n, Make)

The subscribe call of the REST-hook pattern used by Zapier and n8n triggers: creates a webhook for one event (or several) and returns its id and secret.

Scope: webhooks

Body

target_urlstringrequired
URL to call (also url or hookUrl).
eventstring
One event type.
eventsstring[]
Or several.
descriptionstring
Label.
Request
curl -X POST "https://meetzy.me/api/v1/hooks" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_url": "https://hooks.zapier.com/hooks/standard/123/abc",
    "event": "contact.created"
  }'
const res = await fetch("https://meetzy.me/api/v1/hooks", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "target_url": "https://hooks.zapier.com/hooks/standard/123/abc",
    "event": "contact.created"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/hooks",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "target_url": "https://hooks.zapier.com/hooks/standard/123/abc",
        "event": "contact.created"
    },
)
data = res.json()
Response201
{
  "id": "23567d4a-13b9-4120-a41b-0e66036a6c47",
  "secret": "whsec_8f3c…",
  "events": [
    "contact.created"
  ]
}
DELETE/hooks/{id}

Unsubscribe a REST hook

Scope: webhooks

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X DELETE "https://meetzy.me/api/v1/hooks/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/hooks/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://meetzy.me/api/v1/hooks/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "deleted": true
}
GET/hooks/sample

Sample payload for an event

An array with one example delivery for an event, built from your latest matching record — what Zapier / n8n show while you map fields.

Scope: read

Query parameters

eventstring
Event type. Default contact.created.
Request
curl "https://meetzy.me/api/v1/hooks/sample?event=deal.won" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/hooks/sample?event=deal.won", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/hooks/sample?event=deal.won",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
[
  {
    "id": "evt_sample",
    "type": "deal.won",
    "created_at": "2026-10-07T13:23:49.451Z",
    "entity": {
      "type": "deal",
      "id": "d74acfa5-9877-4d7f-a369-3a505bac042a"
    },
    "data": {
      "record": {
        "id": "d74acfa5-9877-4d7f-a369-3a505bac042a",
        "user_from": "acme",
        "name": "Payfit — rollout",
        "pipeline_id": "cacafee6-6c63-407f-a948-5d6570c20143",
        "stage_id": "proposal",
        "status": "open",
        "amount": 12000,
        "currency": "EUR",
        "probability": null,
        "close_date": "2026-11-06",
        "owner_email": "olivia@acme.com",
        "company_id": "166c436d-a874-4730-a0d8-c8d7fa090268",
        "primary_lead_id": "8028ff76-1da4-451f-a0e7-dd91db772c20",
        "priority": "medium",
        "deal_type": "new_business",
        "source": null,
        "recurring": false,
        "mrr": null,
        "next_step": null,
        "next_step_date": null,
        "description": null,
        "lost_reason": null,
        "won_reason": null,
        "competitors": [],
        "tags": [],
        "custom": {},
        "stage_entered_at": "2026-10-07T13:22:51.622676+00:00",
        "stage_history": [
          {
            "at": "2026-10-07T13:22:51.622676+00:00",
            "to": "proposal",
            "from": "qualification",
            "days_in_stage": 0.000041483657407407404
          }
        ],
        "closed_at": null,
        "last_activity_at": null,
        "created_by": "olivia@acme.com",
        "created_at": "2026-10-07T13:22:48.038488+00:00",
        "updated_at": "2026-10-07T13:22:53.559344+00:00"
      }
    }
  }
]
GET/events

Event log

The latest events of the workspace, newest first: type, record, payload, when it happened and when workflows and webhooks processed it. Handy to debug or to poll instead of receiving webhooks.

Scope: read

Query parameters

typestring
One event type.
limitinteger
Default 50.
Request
curl "https://meetzy.me/api/v1/events?type=deal.won&limit=20" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/events?type=deal.won&limit=20", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/events?type=deal.won&limit=20",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "events": [
    {
      "id": 3307,
      "type": "sequence.exited",
      "entity_type": "contact",
      "entity_id": "8028ff76-1da4-451f-a0e7-dd91db772c20",
      "payload": {
        "reason": "manual",
        "sequence_id": "8ff666e1-a95c-4b4a-ad4b-250fa13794be",
        "enrollment_id": "7be8416d-3e67-4ec7-a1ed-c590f7d02299"
      },
      "created_at": "2026-10-07T13:23:11.315289+00:00",
      "processed_at": "2026-10-07T13:23:12.064+00:00"
    },
    {
      "id": 3306,
      "type": "task.created",
      "entity_type": "task",
      "entity_id": "e3ecc019-a3ac-4a49-a642-3fbec133aa2e",
      "payload": {
        "id": "e3ecc019-a3ac-4a49-a642-3fbec133aa2e",
        "type": "todo",
        "owner": "olivia@acme.com",
        "title": "Intro call",
        "due_at": "2026-10-07T17:23:10.013+00:00",
        "source": "sequence",
        "deal_id": null,
        "lead_id": "8028ff76-1da4-451f-a0e7-dd91db772c20"
      },
      "created_at": "2026-10-07T13:23:10.037612+00:00",
      "processed_at": "2026-10-07T13:23:12.064+00:00"
    }
  ]
}

What a delivery looks like

A POST with a JSON body. data summarises the record at the time of the event (name, owner, stage, amount…) with what changed — from / to for moves, changed for property changes — and data.record is the full record as it is now (contact, deal, company, task or quote). Answer with any 2xx within 10 seconds.

{
  "id": "evt_3307",
  "type": "deal.won",
  "created_at": "2026-10-07T10:02:10Z",
  "organization": "acme",
  "entity": {
    "type": "deal",
    "id": "5eecc043-d70d-4b94-a604-7e1a35d92edf"
  },
  "data": {
    "id": "5eecc043-d70d-4b94-a604-7e1a35d92edf",
    "name": "Payfit — rollout",
    "owner": "olivia@acme.com",
    "from": "negotiation",
    "to": "won",
    "stage": "won",
    "status": "won",
    "amount": 12000,
    "currency": "EUR",
    "close_date": "2026-11-06",
    "company_id": "3cdc3e21-931a-4e8b-a189-3cab5dfbd636",
    "pipeline_id": "cacafee6-6c63-407f-a948-5d6570c20143",
    "record": {
      "id": "5eecc043-d70d-4b94-a604-7e1a35d92edf",
      "name": "Payfit — rollout",
      "amount": 12000,
      "currency": "EUR",
      "status": "won",
      "stage_id": "won",
      "owner_email": "olivia@acme.com",
      "company_id": "3cdc3e21-931a-4e8b-a189-3cab5dfbd636",
      "primary_lead_id": "e43414d6-f56f-42be-a64c-a836d6015efc",
      "closed_at": "2026-10-07T10:02:09Z",
      "…": "…"
    }
  },
  "test": false
}
HeaderValue
X-Meetzy-EventThe event type, e.g. deal.won
X-Meetzy-DeliveryId of the event — the same on every retry: use it to ignore duplicates
X-Meetzy-Attempt1 for the first try, then 2, 3…
X-Meetzy-TimestampUnix time (seconds) of this attempt
X-Meetzy-Signaturesha256=HMAC_SHA256(secret, timestamp + "." + raw body), in hex
User-AgentMeetzy-Webhooks/1.0

Verify the signature

Compute the HMAC of {timestamp}.{raw body} with the webhook’s secret and compare it, in constant time, to the header. Reject old timestamps to stop replays. Use the raw body exactly as received — not re-serialised JSON.

Node.js
import crypto from "node:crypto";

// Express: app.post("/meetzy", express.raw({ type: "application/json" }), handler)
function verify(req, secret) {
  const ts = req.header("X-Meetzy-Timestamp");
  const sig = req.header("X-Meetzy-Signature");          // "sha256=…"
  const body = req.body.toString("utf8");                 // the raw body
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(`${ts}.${body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;   // 5 minutes
  return fresh && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
Python
import hmac, hashlib, time

def verify(headers, raw_body: bytes, secret: str) -> bool:
    ts = headers["X-Meetzy-Timestamp"]
    expected = "sha256=" + hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    fresh = abs(time.time() - int(ts)) < 300
    return fresh and hmac.compare_digest(expected, headers["X-Meetzy-Signature"])
PHP
<?php
$ts = $_SERVER['HTTP_X_MEETZY_TIMESTAMP'];
$raw = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $raw, $secret);
$ok = abs(time() - (int) $ts) < 300 && hash_equals($expected, $_SERVER['HTTP_X_MEETZY_SIGNATURE']);

Retries

A delivery that fails with a network error, a 5xx, 408 or 429 is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours (6 attempts in all). Other 4xx are not retried — your endpoint refused the payload. After 25 failures in a row the webhook is switched off (active: false); turn it back on with PATCH /webhooks/{id}. Every attempt is in the delivery log and can be resent.

Event types

EventWhenGroup
contact.createdContact createdContacts
contact.stage_changedContact pipeline stage changedContacts
contact.status_changedContact status changedContacts
contact.lifecycle_changedLifecycle stage changedContacts
contact.score_changedLead score changedContacts
contact.owner_changedContact owner changedContacts
contact.repliedContact replied (email, LinkedIn, WhatsApp)Contacts
contact.email_sentYou emailed the contact (any mailbox: Outlook, Gmail…)Contacts
contact.email_receivedThe contact emailed you (any mailbox)Contacts
contact.message_receivedWhatsApp / LinkedIn message receivedContacts
contact.message_sentYou sent a WhatsApp / LinkedIn message (any device)Contacts
contact.email_openedEmail openedContacts
contact.email_clickedEmail link clickedContacts
contact.website_visitVisited the websiteContacts
contact.meeting_bookedMeeting bookedContacts
contact.linkedin_connectedLinkedIn invitation acceptedContacts
contact.tags_changedLabels / tags changedContacts
contact.note_addedNote addedContacts
contact.property_changedContact property changedContacts
contact.deletedContact deletedContacts
deal.createdDeal createdDeals
deal.stage_changedDeal stage changedDeals
deal.wonDeal wonDeals
deal.lostDeal lostDeals
deal.reopenedDeal reopenedDeals
deal.amount_changedDeal amount changedDeals
deal.owner_changedDeal owner changedDeals
deal.rottingDeal stuck in stage too longDeals
deal.overdueDeal past its close dateDeals
deal.property_changedDeal property changedDeals
company.createdCompany createdCompanies
company.lifecycle_changedCompany lifecycle changedCompanies
task.createdTask createdTasks
task.completedTask completedTasks
task.overdueTask overdueTasks
quote.sentQuote sentQuotes
quote.viewedQuote viewedQuotes
quote.acceptedQuote acceptedQuotes
quote.declinedQuote declinedQuotes
sequence.enrolledEnrolled in sequenceSequences
sequence.completedSequence completedSequences
sequence.exitedExited sequenceSequences
email.sentEmail sent (campaign or workflow)Email
email.openedEmail openedEmail
email.clickedLink clicked in an emailEmail
email.failedEmail could not be sentEmail
contact.unsubscribedContact unsubscribedEmail
webhook.receivedInbound webhook (n8n, Zapier, forms…)External
form.submittedForm submittedExternal
workflow.enrolledEnrolled manually (CRM, another workflow, API, Claude)External