Triggers
Triggers automatically run an agent when something happens — no schedule required. Where a Job runs an agent on a fixed clock, a Trigger runs an agent in reaction to an event, letting your workspace respond the moment something changes.
ToothFairyAI supports two event sources:
- Native — ToothFairyAI's own platform events (a document is created, an agent completes, a planner is awaiting approval, etc.).
- External — Trigger events emitted by third-party apps (Google Drive, Slack, GitHub, Salesforce, Stripe, Notion, Jira, and many more). External triggers are acquired by polling the provider with a configured Authorisation.
When a trigger fires, it sends the bound prompt (or forced prompt) to the selected agent exactly as a manual chat run would.
Menu location
Triggers can be created and managed from the following menu:
Settings > Triggers > Create trigger
Create a trigger
Basic Information
- Click on the
Create triggerbutton. - Name — Assign a unique name to identify the trigger.
- Description (optional) — Describe what this trigger does and when it should fire.
Execution Configuration
- Agent — Select the agent that will run when the trigger fires. Voice-mode agents are excluded from the dropdown (triggers target text-capable agents).
- Prompt — Choose the prompt sent to the agent. Available prompts are your saved prompts (see Prompting). The dropdown only lists prompts made available to the selected agent. You can provide a Forced Prompt instead — free-text instructions (max 1024 characters) used directly as the agent's input. Either a prompt or a forced prompt is required.
If the selected agent has no prompts assigned to it — and you have not provided a forced prompt — the form shows a placeholder linking you straight to the Generation settings section to create one.
Event Configuration
- Event Source — Choose where the triggering event comes from:
Native (ToothFairyAI events)
React to events produced inside your ToothFairyAI workspace.
-
Native Event Type — The platform event to listen for (e.g.
document.created,agent_completed,planner_pending_approval). See the Native events table below. -
Data Filter (optional) — Narrow the trigger to events whose payload matches conditions you define. Each row is a
field / operator / valuetriple:Operator Meaning equalsField equals the value not equalsField does not equal the value includesField contains the value greater thanField is numerically greater than the value less thanField is numerically less than the value existsField is present in the payload Add as many rows as you need; an event must satisfy all rows to fire. Empty
fieldrows are ignored on save.
External (3rd-party app)
React to events emitted by an external provider.
- Provider — The third-party app to listen to (e.g. Google Drive, Slack, GitHub). Providers that are registered but not yet fully implemented are shown with a
(soon)badge and cannot be saved until their adapter lands. - Provider Event — The specific event from the provider (e.g.
drive.file.created,slack.message.mentioned,github.pr.merged). - Authorisation — The credential the trigger will use to poll the provider. The dropdown lists every Authorisation you have configured in the workspace; the selected authorisation's type is stored as the trigger's authorisation type on save.
- Acquisition Mode — How ToothFairyAI acquires the event:
- Polling (default) — Periodically polls the provider's API for new items.
- Webhook (soon) — Receive push events from the provider. Not yet available.
- Poll Interval (Polling only) — How often to poll. Options: 1, 2, 5, 10, or 30 minutes (default 5 minutes).
- Poll Endpoint (Generic REST provider only) — The full URL to poll, e.g.
https://api.example.com/v1/items. - JSONPath (Generic REST provider only) — The JSONPath expression used to extract the list of new items from each poll response, e.g.
$.items[*].
External triggers need a provider Authorisation to authenticate the poll. If no Authorisations exist when an external provider is selected, the form shows a hint — create an Authorisation first, then return to the trigger.
Status
-
Active — Toggle to arm or pause the trigger. When active, the trigger is saved with status ARMED and will fire on matching events. When inactive it is saved as PAUSED and will not fire until re-enabled.
-
Click on the
Createbutton to save the trigger.
Native events
These are ToothFairyAI's own platform events, organized by category:
| Event ID | Category | Label | Description |
|---|---|---|---|
document.created | documents | Document Created | A new document has been created in the workspace |
document.updated | documents | Document Updated | An existing document has been modified |
document.deleted | documents | Document Deleted | A document has been deleted from the workspace |
agent_completed | agent | Agent Completed | An agent has successfully completed processing a chat message |
agent_failed | agent | Agent Failed | An agent encountered an error while processing a chat message |
planner_completed | planner | Planner Completed | A planner has successfully completed all plan steps |
planner_failed | planner | Planner Failed | A planner encountered an error during execution |
planner_pending_approval | planner | Planner Pending Approval | A generated plan is awaiting user approval |
planner_stopped | planner | Planner Stopped | Plan execution was stopped by the user |
Native events are the same events ToothFairyAI emits over its webhooks. Pairing a trigger with a native event is the in-app way to react to those same lifecycle events.
External providers
The provider catalog is served live from the ToothFairyAI backend and rendered in the form, so new providers appear automatically. The providers below are currently implemented (field-complete polling adapters):
| Provider | Auth type | Example events |
|---|---|---|
| Google Drive | OAuth | drive.file.created, drive.file.updated, drive.file.deleted, drive.folder.created |
| Microsoft Graph (SharePoint / Azure / OneDrive) | OAuth | graph.drive.item.created, graph.list.item.created, graph.calendar.event.created, graph.mail.received |
| Slack | OAuth | slack.message.posted, slack.message.mentioned, slack.reaction.added, slack.file.shared |
| GitHub | OAuth | github.issue.opened, github.pr.merged, github.push, github.release.published, github.star.created |
| Notion | OAuth | notion.page.created, notion.page.updated, notion.database.created |
| Dropbox | OAuth | dropbox.file.created, dropbox.file.updated, dropbox.file.deleted, dropbox.folder.created |
| Box | OAuth | box.file.created, box.file.updated, box.file.deleted, box.comment.created |
| OneDrive | OAuth | onedrive.file.created, onedrive.file.updated, onedrive.file.deleted |
| Salesforce | OAuth | salesforce.lead.created, salesforce.opportunity.updated, salesforce.case.created, salesforce.custom.object.created |
| HubSpot | OAuth | hubspot.contact.created, hubspot.deal.created, hubspot.ticket.created, hubspot.form.submitted |
| Linear | OAuth | linear.issue.created, linear.issue.status.changed, linear.project.created |
| Jira | OAuth | jira.issue.created, jira.issue.updated, jira.sprint.started, jira.version.released |
| Asana | OAuth | asana.task.created, asana.task.completed, asana.project.created |
| Trello | OAuth | trello.card.created, trello.card.moved, trello.card.commented |
| Zendesk | Basic | zendesk.ticket.created, zendesk.ticket.assigned, zendesk.user.created |
| ServiceNow | Basic | servicenow.incident.created, servicenow.change.request.created, servicenow.problem.created |
| YouTube | OAuth | youtube.video.uploaded, youtube.comment.created, youtube.subscriber.threshold |
| Gmail | OAuth | gmail.message.received, gmail.message.received.label, gmail.message.sent |
| Google Calendar | OAuth | calendar.event.created, calendar.event.started, calendar.event.attendee.response, calendar.reminder |
| Microsoft Forms | OAuth | forms.response.created, forms.response.updated, forms.form.created |
| Microsoft Teams | OAuth | teams.message.created, teams.message.mentioned, teams.channel.created, teams.member.added |
| Stripe | API Key | stripe.payment.intent.succeeded, stripe.charge.refunded, stripe.customer.created, stripe.subscription.created, stripe.invoice.paid |
| Generic REST (API Key / OAuth) | API Key | generic.poll — periodically GET a custom REST endpoint and emit items via JSONPath |
Each provider exposes its own event list in the Provider Event dropdown; only events valid for the selected provider are shown.
For a handful of providers (Slack, GitHub, Box, Linear, Zendesk, Stripe) the native acquisition mode is webhook-based; ToothFairyAI implements a polling adapter for these as a functional fallback, with webhook ingestion arriving in a later release.
Managing triggers
Once created, triggers appear in the triggers list with their name, bound agent, event source, and status.
| Status | Meaning |
|---|---|
| ARMED | Trigger is active and will fire on matching events |
| PAUSED | Trigger is inactive and will not fire |
Edit a trigger
- Click on an existing trigger from the list.
- The edit modal displays the trigger ID and all configuration options.
- Modify any settings as needed.
- Click
Saveto update the trigger.
Delete a trigger
- Open the trigger you want to delete.
- Click the
Deletebutton at the bottom of the edit modal. - Confirm the deletion when prompted.
Triggers vs Jobs
| Triggers | Jobs | |
|---|---|---|
| Runs on | An event occurring | A fixed schedule |
| Best for | Real-time reaction to changes | Repetitive, clock-driven tasks |
| Event scope | Native platform events or 30+ external providers | Your workspace only |
| Acquisition | Polling (webhook soon) | Internal scheduler |
For proactive, time-boxed automation use a Job; for reactive, event-driven automation use a Trigger. Combine both — e.g. a Slack-triggered agent that runs on every new mention, plus a daily routine job that summarizes the day's activity.
Use cases
Native
- Document lifecycle — Re-index or summarize a document the moment it's created or updated.
- Agent completion — Trigger a downstream agent (notification, logging) whenever another agent finishes.
- Planner approval — Send a Slack or email alert when a generated plan is awaiting approval.
External
- Support triage —
zendesk.ticket.created→ an agent drafts a first-pass response and suggests a category. - Sales follow-up —
hubspot.deal.created/salesforce.opportunity.updated→ an agent drafts a tailored follow-up email. - Code review assist —
github.pr.opened→ an agent reads the diff and posts a review checklist. - Inbound email triage —
gmail.message.received(label) → an agent categorizes and routes the email. - Payment alerts —
stripe.charge.dispute.created→ an agent summarizes the dispute and drafts a customer response. - Calendar reminders —
calendar.event.starts→ an agent prepares an agenda from related materials. - Custom API —
generic.pollagainst your own REST endpoint → an agent acts on every new item.
Best practices
- Pick the lightest source — Prefer a Native event over an external poll when the workflow only needs to react to something inside ToothFairyAI.
- Use data filters — Narrow Native triggers with data-filter rows so the agent only fires on events it actually needs to act on.
- Right-size the poll interval — Use the smallest interval that still avoids hitting a provider's rate limits. 30 minutes is plenty for slow-moving data; 1–2 minutes only when latency matters.
- Scope prompts to the agent — Assign the bound prompt to the trigger's agent (via
availableToAgents) so the dropdown shows only relevant prompts. - Reuse Authorisations — One provider Authorisation can back several triggers; configure it once in Authorisations and reuse it.
- Naming — Use descriptive names that state provider + event + intent, e.g. "Slack mention → triage agent".
- Start armed, observe first — Arm the trigger and watch a few fires' outputs in External chats before relying on it in production.
- Pause, don't delete — Temporarily pausing a trigger keeps its configuration intact while you investigate or re-tune.
Triggers are subject to the same execution limits as manual agent runs — token limits, execution timeouts, and rate limits based on your subscription tier. Averted triggers still consume a poll against the provider's API on each interval.
Only agents that have been previously created and saved in your workspace appear in the agent dropdown. Voice-mode agents are excluded. Ensure the necessary agent is configured before creating a trigger.