Generative Triggers
Triggers are actions that the LLM can call automatically during a conversation. They connect the assistant to external systems: APIs, CRMs, calendars, health platforms: without the user needing to notice.
How It Works
User: "I want to schedule for tomorrow at 2 PM"
↓
LLM analyzes the message
LLM identifies: "I need to call schedule_appointment"
↓
Platform executes the trigger
(e.g.: Google Calendar API)
↓
Integration response returns to LLM
↓
LLM (if InterpretResponse=true): "Your appointment is scheduled!"
LLM (if InterpretResponse=false): action executed silentlyThe LLM decides when and whether to call a trigger based on the provided description and conversation context.
Trigger Structure
Function Calling
Each trigger exposes a function to the LLM via JSON Schema:
{
"name": "check_order_status",
"description": "Checks the current status of an order by number. Use when the customer asks about the progress, location, or estimated delivery of an order.",
"parameters": {
"type": "object",
"properties": {
"order_number": {
"type": "string",
"description": "Order number, usually in the format ORD-XXXXX"
},
"include_history": {
"type": "boolean",
"description": "Whether to include the full movement history"
}
},
"required": ["order_number"]
}
}FunctionCalling Fields
| Field | Required | Description |
|---|---|---|
name |
✅ | Function identifier (no spaces, use _) |
description |
✅ | Crucial: explains WHEN the LLM should call. Max 350 chars |
parameters |
➖ | JSON Schema of arguments the LLM must extract |
The Importance of Description
The description is what the LLM uses to decide whether to call the trigger. A poor description leads to incorrect or missing calls.
Bad description:
"Schedules appointments"Good description:
"Schedules a medical appointment in the system. Use when the patient
confirms they want to schedule, after already choosing doctor, date, and time.
Do NOT use just to check availability."Tips for a good description:
- State when to use (context)
- State when NOT to use (avoids false positives)
- Use action verbs in imperative form
- Mention what the LLM needs to collect from the user before calling
Parameters and Automatic Extraction
The LLM automatically extracts the defined parameters from the conversation context. You don't need to explicitly ask for each piece of data: the LLM knows what it needs to collect.
{
"name": "create_crm_lead",
"parameters": {
"properties": {
"name": { "type": "string", "description": "Customer's full name" },
"email": { "type": "string", "description": "Customer's email" },
"company": { "type": "string", "description": "Company name where they work" },
"interest": {
"type": "string",
"enum": ["basic", "pro", "enterprise"],
"description": "Customer's plan of interest"
}
},
"required": ["name", "email"]
}
}If name and email have already been mentioned in the conversation, the LLM uses them directly. Otherwise, it may ask the user before calling.
`MaxInteractions`
Defines how many times the LLM can call triggers in sequence for a single user message.
| Value | Behavior |
|---|---|
1 |
Calls at most 1 trigger per response |
2 (default) |
Can call 1 trigger, receive the response, and call 1 more |
3-10 |
Allows more complex flows with multiple steps |
Example with MaxInteractions = 3:
User: "Schedule for Lucas, ID 123-45-6789"
↓
LLM calls: find_patient(id="123-45-6789")
↓
System returns: {id: "pat_42", name: "Lucas Smith", ...}
↓
LLM calls: check_availability(patient_id="pat_42")
↓
System returns: ["2 PM", "3 PM", "4 PM tomorrow"]
↓
LLM asks: "Lucas, I have slots available tomorrow: 2 PM, 3 PM, or 4 PM. Which do you prefer?"`InterpretResponse`
Controls whether the LLM reads and interprets the integration's response to formulate a reply to the user.
| Value | Behavior |
|---|---|
true |
LLM receives the trigger's response and decides what to tell the user |
false |
Action is executed silently; LLM responds without seeing the result |
When to use false:
- Log/analytics actions (Meta Pixel, event tracking)
- Background actions that don't affect the response (CRM update)
- When you want to control the confirmation message via
responseDirective
`CopilotOnly`
Marks the trigger to be used exclusively in copilot mode. In normal sessions, this trigger is ignored.
Useful for:
- Internal backoffice actions that the end user shouldn't trigger
- Analytics and BI integrations
- Moderation/supervision tools
Available Actions per Trigger
Each trigger is associated with an integration action. Available options:
| Action | Subtype | Description |
|---|---|---|
WEBHOOK |
: | Custom HTTP (GET, POST, PUT, DELETE) |
NATIVE |
SEND_TEXT, SEND_BUTTON, SEND_LIST... | Advanced WhatsApp messages |
CRM |
UPSERT_CONTACT | Create/update contact |
GOOGLE_CALENDAR |
CHECK, LIST, SCHEDULE | Scheduling |
KNOWLEDGE |
SEARCH | Knowledge base search |
META_ADS |
SEND_EVENT | Conversion pixel |
CHAT_INTEGRATION |
CHANGE_STATUS, SUMMARIZE | Human handoff |
CATALOG |
SEARCH, ADD_CART... | Product catalog |
FEEGOW |
24 subtypes | Clinical management |
Z_API / MY_ZAP / EVOLUTION |
SET_TAG, RESET_SESSION... | WhatsApp management |
Full Example: Sales Assistant
{
"triggers": [
{
"name": "qualify_lead",
"description": "Records a qualified lead in the CRM after collecting name, email, and interest. Use when the customer shows genuine interest in the product.",
"parameters": {
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"interest": {
"type": "string",
"enum": ["demo", "proposal", "information"]
}
},
"required": ["name", "email", "interest"]
},
"action": { "type": "CRM", "subtype": "UPSERT_CONTACT" },
"interpretResponse": false
},
{
"name": "schedule_demo",
"description": "Schedules a demo on Google Calendar. Use ONLY after the lead confirms their name, email, and has chosen a specific date/time.",
"parameters": {
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"datetime": { "type": "string", "description": "Date and time in ISO 8601 format" }
},
"required": ["name", "email", "datetime"]
},
"action": { "type": "GOOGLE_CALENDAR", "subtype": "SCHEDULE" },
"interpretResponse": true
}
]
}