Trigger Functions
Trigger functions execute automatically when data changes in a collection. Use them for validation, transformation, notifications, and integrations.
How It Works
- Configure which collection to monitor
- Select which operations trigger execution (POST, PUT, PATCH, DELETE)
- Write JavaScript code or configure an external webhook
- Function runs automatically on matching operations
Configuration
Basic Settings
| Setting | Description |
|---|---|
| Name | Unique identifier for the function |
| Description | Optional documentation |
| Enabled | Toggle to enable/disable without deleting |
| Collection | The collection to monitor |
| Methods | Which operations trigger execution |
Triggering Methods
| Method | When It Fires |
|---|---|
POST | New item created |
PUT | Item replaced |
PATCH | Item updated |
DELETE | Item deleted |
Select one or more methods. The function fires for each matching operation.
Execution Context
What Your Code Receives
| Object | Description |
|---|---|
item | The record being created, updated, or deleted |
me | The user who triggered the change |
req | Request details (method, headers, query) |
api | API information |
secrets | Configured secrets |
Token Options
Control whose permissions the function uses:
| Option | Description |
|---|---|
| None | No authentication (anonymous) |
| Current User | Execute as the user who triggered the change |
| Service Account | Execute with service account permissions |
Execution Control
| Option | Description |
|---|---|
| Skip Security Policy | Bypass row-level access control |
| Skip Roles | Ignore role-based permissions |
| Halt on Error | Stop the operation if the function fails |
Use Cases
Data Validation
Validate data before it's saved:
// Reject orders with invalid totals
if (item.total < 0) {
throw new Error('Order total cannot be negative');
}
if (item.items.length === 0) {
throw new Error('Order must have at least one item');
}
Data Transformation
Transform values before saving:
// Auto-generate slug from title
item.slug = item.title
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '');
// Set timestamps
item.updatedAt = new Date().toISOString();
item.updatedBy = me.id;
Notifications
Send notifications on changes (requires paid tier):
// Notify when order status changes
if (item.status === 'shipped') {
await fetch('https://api.email-service.com/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
to: item.customerEmail,
subject: 'Your order has shipped!',
body: `Order ${item.orderNumber} is on its way.`
})
});
}
External Sync
Sync data with external systems (requires paid tier):
// Sync customer to CRM
await fetch('https://crm.example.com/api/contacts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${secrets.CRM_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: item.email,
name: item.name,
source: 'website'
})
});
Cascade Operations
Perform related operations using built-in methods:
// When a project is deleted, archive its tasks
if (req.method === 'DELETE') {
const tasks = await get(`tasks?filter=projectId eq "${item.id}"`);
for (const task of tasks) {
await patch(`tasks/${task.id}`, { archived: true });
}
}
External Endpoint Action
Instead of JavaScript, call an external webhook:
| Setting | Description |
|---|---|
| URL | The webhook endpoint to call |
| Custom Headers | Additional headers to include |
| Send Token | Include authentication token |
| Halt on Error | Stop if webhook fails |
The webhook receives the same context as JavaScript functions.
Best Practices
- Keep functions focused — One function, one responsibility
- Handle errors gracefully — Use try-catch and meaningful error messages
- Use Halt on Error carefully — Only when the operation should fail if the function fails
- Test thoroughly — Use the built-in test runner before enabling
- Log important events — Use console.log for debugging and auditing