Triggers API
Triggers enable automatic responses and actions based on user input patterns. They provide a powerful way to handle common user requests without requiring AI processing, improving response time and consistency.
Overview
Triggers work in two phases:
- Keyword Triggers — Matched before AI processing (instant response)
- Intent Triggers — Matched after AI processing (requires AI to detect intent)
User: "show me pricing"
↓
┌─────────────────────┐
│ Keyword Matching │ ← Phase 1: Check for "pricing" keyword
└─────────────────────┘
↓ (no match or skipAgent: false)
┌─────────────────────┐
│ AI Processing │ ← AI generates response, extracts intent
└─────────────────────┘
↓
┌─────────────────────┐
│ Intent Matching │ ← Phase 2: Check for detected intent
└─────────────────────┘
↓
Response with actions/content
Trigger Object
interface Trigger {
id: string;
type: 'keyword' | 'intent';
trigger: {
value: string; // Keyword pattern or intent name
confidence?: number; // For intents: minimum confidence (0-1)
examples?: string[]; // For intents: training examples
};
response?: {
contentId?: string; // Return specific content
message?: string; // Return direct message
};
actions?: ClientAction[];
options?: {
skipAgent?: boolean; // Skip AI entirely (keyword triggers)
actionsOnly?: boolean; // Only return actions, no content
priority?: number; // Higher = checked first
};
enabled: boolean;
tags?: string[];
createdAt: string;
updatedAt: string;
}
Keyword Patterns
Keyword triggers support several matching patterns:
| Pattern | Example | Matches |
|---------|---------|---------|
| Simple | "pricing" | Input contains "pricing" |
| Exact | "[pricing]" | Input is exactly "pricing" |
| AND | "red+wine" | Input contains both "red" AND "wine" |
| Multiple | "hi,hello,hey" | Input contains any: "hi", "hello", or "hey" |
Examples
// Simple match - matches "show me pricing" or "pricing info"
{ type: 'keyword', trigger: { value: 'pricing' } }
// Exact match - only matches exactly "help"
{ type: 'keyword', trigger: { value: '[help]' } }
// AND match - "I want a red wine" matches
{ type: 'keyword', trigger: { value: 'red+wine' } }
// Multiple - any greeting matches
{ type: 'keyword', trigger: { value: 'hi,hello,hey,howdy' } }
API Endpoints
List Triggers
GET /api/sdk/triggers
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| type | keyword \| intent | Filter by trigger type |
| enabled | true \| false | Filter by status |
| tag | string | Filter by tag |
| limit | number | Results per page (default: 50, max: 100) |
| offset | number | Pagination offset |
Response:
{
"success": true,
"data": {
"triggers": [
{
"id": "trigger_abc123",
"type": "keyword",
"trigger": {
"value": "pricing",
"confidence": 0.7,
"examples": []
},
"response": {
"message": "Our pricing starts at $29/month. Check out fig1.ai/pricing for details!"
},
"actions": [
{
"type": "navigate",
"payload": { "route": "/pricing" },
"priority": 1
}
],
"options": {
"skipAgent": true,
"actionsOnly": false,
"priority": 10
},
"enabled": true,
"tags": ["navigation"],
"createdAt": "2024-12-21T10:00:00Z",
"updatedAt": "2024-12-21T10:00:00Z"
}
],
"pagination": {
"total": 15,
"limit": 50,
"offset": 0,
"hasMore": false
}
}
}
Example:
curl -X GET "https://app.fig1.ai/api/sdk/triggers?type=keyword&enabled=true" \
-H "X-Fig1-API-Key: fig1_sdk_your_api_key"
Create Trigger
POST /api/sdk/triggers
Request Body:
{
type: 'keyword' | 'intent'; // Required
trigger: {
value: string; // Required: keyword pattern or intent name
confidence?: number; // Optional: 0-1 (default: 0.7)
examples?: string[]; // Optional: training examples for intents
};
response?: {
contentId?: string; // Optional: content composition ID
message?: string; // Optional: direct message response
};
actions?: Array<{
type: string;
payload: object;
priority?: number;
label?: string;
}>;
options?: {
skipAgent?: boolean; // Default: false
actionsOnly?: boolean; // Default: false
priority?: number; // Default: 0
};
enabled?: boolean; // Default: true
tags?: string[];
}
Response:
{
"success": true,
"data": {
"id": "trigger_new123",
"type": "keyword",
"trigger": { "value": "pricing", "confidence": 0.7, "examples": [] },
"response": { "message": "Check out our pricing page!" },
"actions": [],
"options": { "skipAgent": true, "actionsOnly": false, "priority": 0 },
"enabled": true,
"tags": [],
"createdAt": "2024-12-21T10:00:00Z",
"updatedAt": "2024-12-21T10:00:00Z"
}
}
Examples:
Keyword trigger with navigation action
curl -X POST https://app.fig1.ai/api/sdk/triggers \
-H "Content-Type: application/json" \
-H "X-Fig1-API-Key: fig1_sdk_your_api_key" \
-d '{
"type": "keyword",
"trigger": { "value": "pricing,prices,cost" },
"response": { "message": "Let me take you to our pricing page!" },
"actions": [
{
"type": "navigate",
"payload": { "route": "/pricing" },
"priority": 1
}
],
"options": { "skipAgent": true },
"tags": ["navigation"]
}'
Intent trigger for booking
curl -X POST https://app.fig1.ai/api/sdk/triggers \
-H "Content-Type: application/json" \
-H "X-Fig1-API-Key: fig1_sdk_your_api_key" \
-d '{
"type": "intent",
"trigger": {
"value": "book_appointment",
"confidence": 0.8,
"examples": [
"I want to book an appointment",
"Can I schedule a meeting?",
"Book a time slot",
"I need to make a reservation"
]
},
"actions": [
{
"type": "open_modal",
"payload": { "modalId": "booking-calendar" }
}
],
"tags": ["booking"]
}'
Actions-only trigger (no message)
curl -X POST https://app.fig1.ai/api/sdk/triggers \
-H "Content-Type: application/json" \
-H "X-Fig1-API-Key: fig1_sdk_your_api_key" \
-d '{
"type": "keyword",
"trigger": { "value": "dark mode,night mode" },
"actions": [
{
"type": "trigger_event",
"payload": { "eventName": "theme:toggle", "eventData": { "theme": "dark" } }
}
],
"options": { "skipAgent": true, "actionsOnly": true }
}'
Get Trigger
GET /api/sdk/triggers/:id
Response:
{
"success": true,
"data": {
"id": "trigger_abc123",
"type": "keyword",
"trigger": { "value": "pricing", "confidence": 0.7, "examples": [] },
"response": { "message": "Check out our pricing page!" },
"actions": [],
"options": { "skipAgent": true, "actionsOnly": false, "priority": 0 },
"enabled": true,
"tags": ["navigation"],
"createdAt": "2024-12-21T10:00:00Z",
"updatedAt": "2024-12-21T10:00:00Z"
}
}
Update Trigger
PUT /api/sdk/triggers/:id
Request Body (all fields optional):
{
trigger?: {
value?: string;
confidence?: number;
examples?: string[];
};
response?: {
contentId?: string;
message?: string;
};
actions?: ClientAction[];
options?: {
skipAgent?: boolean;
actionsOnly?: boolean;
priority?: number;
};
enabled?: boolean;
tags?: string[];
}
Example:
curl -X PUT https://app.fig1.ai/api/sdk/triggers/trigger_abc123 \
-H "Content-Type: application/json" \
-H "X-Fig1-API-Key: fig1_sdk_your_api_key" \
-d '{
"enabled": false,
"options": { "priority": 20 }
}'
Delete Trigger
DELETE /api/sdk/triggers/:id
Response:
{
"success": true,
"data": {
"id": "trigger_abc123",
"deleted": true
}
}
Action Types
Triggers can include any of these action types:
| Type | Description | Payload Fields |
|------|-------------|----------------|
| navigate | Navigate to app route | route, params |
| open_url | Open external URL | url |
| open_content | Display content | contentId |
| play_video | Play video | videoId, timestamp |
| show_product | Show product details | productId |
| add_to_cart | Add to cart | productId, quantity |
| open_modal | Open modal/dialog | modalId, modalData |
| trigger_event | Fire custom event | eventName, eventData |
| custom | App-specific action | customType, customData |
See Client Actions for detailed handling instructions.
Chat Response Integration
When a trigger matches during chat, the response includes trigger information:
{
"success": true,
"data": {
"message": "Let me take you to our pricing page!",
"sessionId": "sess_abc123",
"actions": [
{
"type": "navigate",
"payload": { "route": "/pricing" },
"priority": 1
}
],
"triggeredBy": {
"type": "keyword",
"value": "pricing"
},
"metadata": {
"model": "keyword-trigger",
"tokensUsed": 0,
"proxyLatencyMs": 15,
"triggerPhase": "pre-agent"
}
}
}
Key Fields
| Field | Description |
|-------|-------------|
| triggeredBy.type | "keyword" or "intent" |
| triggeredBy.value | The matched keyword or intent name |
| metadata.triggerPhase | "pre-agent" (keyword) or "post-agent" (intent) |
| metadata.tokensUsed | 0 for keyword triggers (no AI used) |
Best Practices
1. Use Keywords for Navigation
Keyword triggers skip AI processing entirely, making them ideal for common navigation requests:
// Fast: Instant response, no AI cost
{
type: 'keyword',
trigger: { value: 'contact,support,help' },
response: { message: 'Here\'s our contact page!' },
actions: [{ type: 'navigate', payload: { route: '/contact' } }],
options: { skipAgent: true }
}
2. Use Intents for Complex Requests
Intent triggers leverage AI understanding for nuanced requests:
// Flexible: AI understands variations
{
type: 'intent',
trigger: {
value: 'request_refund',
confidence: 0.75,
examples: [
'I want my money back',
'This isn\'t what I ordered',
'Can I return this?'
]
},
actions: [{ type: 'open_modal', payload: { modalId: 'refund-form' } }]
}
3. Set Appropriate Confidence Thresholds
| Confidence | Use Case | |------------|----------| | 0.9+ | Critical actions (payments, cancellations) | | 0.7-0.9 | Standard actions (navigation, modals) | | 0.5-0.7 | Suggestions (non-critical) |
4. Use Priority for Ordering
Higher priority triggers are checked first:
// Priority 100: Emergency/safety keywords checked first
{ trigger: { value: 'emergency' }, options: { priority: 100 } }
// Priority 50: Important navigation
{ trigger: { value: 'pricing' }, options: { priority: 50 } }
// Priority 0: General triggers (default)
{ trigger: { value: 'hello' }, options: { priority: 0 } }
5. Combine Actions and Messages
Triggers can include both a response message and actions:
{
type: 'keyword',
trigger: { value: 'book' },
response: { message: 'Opening our booking calendar for you!' },
actions: [
{ type: 'open_modal', payload: { modalId: 'booking' } },
{ type: 'trigger_event', payload: { eventName: 'booking:started' } }
],
options: { skipAgent: true }
}
Error Responses
Invalid Trigger ID (400)
{
"success": false,
"error": "Invalid trigger ID"
}
Trigger Not Found (404)
{
"success": false,
"error": "Trigger not found"
}
Duplicate Trigger (409)
{
"success": false,
"error": "A keyword trigger with this value already exists"
}
Invalid Type (400)
{
"success": false,
"error": "type must be \"keyword\" or \"intent\""
}
Missing Value (400)
{
"success": false,
"error": "trigger.value is required"
}