Chat Triggers
Configure automated actions that fire when a chat conversation reaches a terminal event. Triggers are evaluated after a chat turn completes and can call a webhook with the extracted structured data.
Endpoints
GET /api/organizations/{organizationId}/projects/{projectId}/chat-triggers
POST /api/organizations/{organizationId}/projects/{projectId}/chat-triggers
GET /api/organizations/{organizationId}/projects/{projectId}/chat-triggers/{triggerId}
PATCH /api/organizations/{organizationId}/projects/{projectId}/chat-triggers/{triggerId}
DELETE /api/organizations/{organizationId}/projects/{projectId}/chat-triggers/{triggerId}
Authentication and Authorization
These endpoints share the chat-schema scopes:
| Scope | Grants |
|---|---|
chat_schemas:read | List and read triggers |
chat_schemas:write | Create, update, and delete triggers |
Both authenticated dashboard sessions and project API keys are supported.
Concepts
Event — The chat lifecycle moment that activates the trigger. Currently lead_complete (fires when a lead intake conversation finishes).
Criteria — Optional filter expressed as a nested all / any / exists object. If omitted, the trigger fires for every matching event. See Criteria syntax.
Extraction prompt — An optional instruction appended to the AI to extract specific fields from the conversation before the trigger fires.
Action type — What happens when the trigger fires. Currently webhook_post only.
Action config — Parameters for the action. For webhook_post, a url is required.
List Triggers
GET /chat-triggers
Returns all triggers for the project, ordered by last-updated descending.
Response
{
"triggers": [
{
"id": "uuid",
"name": "Send lead to CRM",
"event": "lead_complete",
"criteria": { "exists": "email" },
"schemaId": "schema-uuid",
"schemaName": "Lead Intake v1",
"extractionPrompt": null,
"actionType": "webhook_post",
"actionConfig": { "url": "https://crm.example.com/webhooks/lead" },
"status": "active",
"createdAt": "2026-05-01T10:00:00.000Z",
"updatedAt": "2026-05-01T10:00:00.000Z"
}
]
}
Create Trigger
POST /chat-triggers
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name (1–255 characters) |
actionConfig | object | yes | Action parameters. For webhook_post: { "url": "https://..." } |
event | string | no | lead_complete (default) |
schemaId | string (UUID) | null | no | Attach a Chat Schema — its fields are available in criteria and extraction |
criteria | object | null | no | Filter expression. See Criteria syntax |
extractionPrompt | string | null | no | Additional extraction instruction (max 5000 characters) |
actionType | string | no | webhook_post (default and only supported value) |
status | string | no | active (default) or inactive |
Example
{
"name": "Send lead to CRM",
"event": "lead_complete",
"schemaId": "schema-uuid",
"criteria": { "exists": "email" },
"actionType": "webhook_post",
"actionConfig": { "url": "https://crm.example.com/webhooks/lead" }
}
Response — 201 Created
{
"trigger": {
"id": "uuid",
"name": "Send lead to CRM",
"event": "lead_complete",
"criteria": { "exists": "email" },
"schemaId": "schema-uuid",
"extractionPrompt": null,
"actionType": "webhook_post",
"actionConfig": { "url": "https://crm.example.com/webhooks/lead" },
"status": "active",
"createdAt": "2026-05-08T10:00:00.000Z",
"updatedAt": "2026-05-08T10:00:00.000Z"
}
}
Update Trigger
PATCH /chat-triggers/{triggerId}
Send any subset of the create fields. At least one field must be present.
Example — disable a trigger
{ "status": "inactive" }
Example — change the webhook URL
{
"actionConfig": { "url": "https://new-crm.example.com/webhooks/lead" }
}
Delete Trigger
DELETE /chat-triggers/{triggerId}
Response
{ "success": true }
Criteria Syntax
Criteria are evaluated against the structured data extracted from the conversation. Supported operators:
| Operator | Structure | Meaning |
|---|---|---|
exists | { "exists": "fieldName" } | Field is present and non-null in the extracted data |
all | { "all": [...criteria] } | All nested criteria must match |
any | { "any": [...criteria] } | At least one nested criterion must match |
Operators can be nested arbitrarily deep. If criteria is null or omitted, the trigger always fires.
Examples
Fire only when email was captured:
{ "exists": "email" }
Fire when both email and phone were captured:
{
"all": [
{ "exists": "email" },
{ "exists": "phone" }
]
}
Fire when email or company was captured:
{
"any": [
{ "exists": "email" },
{ "exists": "company" }
]
}
Webhook Payload
When a trigger fires, Syntropy sends a POST request to actionConfig.url with the extracted conversation data as a JSON body.
For triggers without an attached schema, the default payload is:
{
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+15555550100",
"message": "Looking for help with a personal injury case",
"data": {},
"conversationId": "conv-uuid",
"accountId": "project-uuid",
"source": "syntropy"
}
For triggers with an attached schema, data contains the schema-extracted fields and the top-level name / email / phone / message fields come from the default lead extraction pass run in parallel.
Creating a Syntropy Customer from a Chat Lead
Chat triggers write to the chatter object (linked to the conversation), not to the Customers API. To create a canonical customer record from a chat lead, call POST /customers from your webhook handler:
// Your webhook handler (e.g. Express / Next.js route)
app.post("/webhooks/chat-lead", async (req, res) => {
const { name, email, phone, conversationId } = req.body;
await fetch("https://your-domain.com/api/organizations/{orgId}/projects/{projectId}/customers", {
method: "POST",
headers: {
"Authorization": "Bearer syn_sk_xxx",
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
name,
phone,
metadata: { source: "chat", conversationId },
}),
});
res.sendStatus(200);
});
The upsert is idempotent on email — if a customer with that address already exists (e.g. from a previous contact form submission), it will be updated rather than duplicated. See Identity Merge Policy.
Example cURL
# Create a trigger
curl -X POST \
"https://your-domain.com/api/organizations/{orgId}/projects/{projectId}/chat-triggers" \
-H "Authorization: Bearer syn_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Send lead to CRM",
"actionConfig": { "url": "https://crm.example.com/webhooks/lead" },
"criteria": { "exists": "email" }
}'
# List all triggers
curl \
"https://your-domain.com/api/organizations/{orgId}/projects/{projectId}/chat-triggers" \
-H "Authorization: Bearer syn_sk_xxx"
Related
- Chat Schemas — define the fields available to trigger criteria
- Customers API — create and manage canonical customer records from webhook data
- Project API Keys —
chat_schemas:readandchat_schemas:writescopes