Triggers
Configure Action Agent triggers, exact channel ingress paths, event scope, request authentication, reply policy, rate limits, and schedules.
Triggers
Action Agent triggers start Agent sessions from external channels or a recurring schedule. Configure them in the Triggers panel in Action Agent Studio. They are Agent bindings, not Flow start nodes. For graph execution, see Flow triggers.
Action Agent Studio offers Slack, Discord, Teams, email, and scheduled triggers. The Action Agent Studio Chat dock is a separate studio session source, not an inAppChat trigger binding. An Agent can have several channels, but the database allows only one binding per Agent and channel.
Channel triggers are vendor ingress for a saved Agent. They are not public Agent start endpoints, SDK methods, hosted MCP tools, or Flow webhooks. Use the Action Agents REST API for backend integration.
Channels and event scopes
| Channel | Enabled event names | Required scope | Default reply |
|---|---|---|---|
| Slack | message, app_mention, dm | One or more channel IDs | thread |
| Discord | message, mention | One or more channel IDs | reply |
| Teams | message | One or more channel IDs plus a team ID | reply |
received | Mailbox | reply | |
| Scheduled | tick | Recurring schedule and prompt | silent |
A binding with no configured scope rejects every event. For channel bindings, the event filter has one important current behavior:
- when
eventsis non-empty, the incoming event type must be one of the saved names; and - when
eventsis empty, the runtime skips the event-name check and treats the binding as a wildcard for otherwise eligible events.
Action Agent Studio normally saves the channel's available event names. Select at least one event explicitly so an empty list does not broaden the binding beyond your intended event scope. A Slack bot's own messages are ignored before binding matching.
Every channel event that passes ingress matching currently starts a new Agent session. Slack thread timestamps, Discord message IDs, Teams message IDs, or an email sender are stored as optional endUserId correlation metadata; they do not reopen a previous session. Every scheduled tick also creates a new session.
Ingress paths
All ingress endpoints are POST endpoints.
| Channel | Path | Query parameters |
|---|---|---|
| Slack | /api/action-agents/triggers/slack/events | None; the workspace routes the event to an organization connection |
| Discord | /api/action-agents/triggers/discord/events | None; the guild routes the event to an organization connection |
| Teams | /api/action-agents/triggers/teams/events | None; the tenant routes the event to an organization connection |
/api/action-agents/triggers/email/inbound | Required: actionAgentId and organizationId |
Use the complete email URL generated by Action Agent Studio:
/api/action-agents/triggers/email/inbound?actionAgentId={actionAgentId}&organizationId={organizationId}The email path is Agent-scoped. Slack, Discord, and Teams use one platform Events endpoint per channel and can match multiple active Agent bindings in the routed organization. Matching bindings are processed sequentially; a thrown Agent-start or send error can stop the remaining matches for that ingress request. These paths are not included in the public Agent discovery metadata.
Request authentication
The raw request body is required for signature verification.
| Channel | Required material and headers |
|---|---|
| Slack | Platform signing secret; X-Slack-Signature and X-Slack-Request-Timestamp. The runtime verifies a v0 HMAC-SHA256 over v0:{timestamp}:{rawBody} and rejects timestamps more than five minutes from now. |
| Discord | Platform Ed25519 public key; X-Signature-Ed25519 and X-Signature-Timestamp. The runtime verifies the signature over {timestamp}{rawBody} and rejects timestamps more than five minutes from now. |
| Teams | Platform Microsoft OAuth app ID; Authorization: Bearer {Bot Framework JWT}. The JWT must verify for that app ID as its audience. |
Either the raw binding secret in X-Webhook-Secret or X-Email-Webhook-Secret, or an HMAC in X-Webhook-Signature with X-Webhook-Timestamp. The HMAC is SHA-256 over {actionAgentId}.{timestamp}.{rawBody}; an optional sha256= prefix is accepted and the Unix-millisecond timestamp is within five minutes. |
Slack, Discord, and Teams signing material belongs to the platform OAuth applications. Email uses a generated secret stored encrypted on that Agent's binding. Never put these secrets in a prompt, tool argument, browser configuration, or support ticket.
For email, ActionFlows checks actionAgentId and organizationId before the trigger limiter. A missing query ID returns 400 without consuming the 10-per-10-second trigger-window slot. After that check, invalid JSON returns 400; an invalid raw secret or HMAC returns 401.
Slack, Discord, and Teams use vendor authentication rather than an email binding secret. Missing or invalid Slack/Discord signatures or Teams Bot Framework authorization returns 401 after the trigger limiter runs.
Rate and body limits
The four handlers share a 10 requests per 10 seconds sliding-window limit. Email query-ID validation is the one exception: it runs first, so a missing email query ID returns 400 before the trigger limiter. For requests that continue, the limiter runs before vendor authentication and JSON parsing.
- Platform events use a channel-plus-client-IP key.
- Email uses channel-plus-Agent-plus-client-IP.
A trigger-window rejection returns 429. The API service also applies a broader per-IP limit of 100 requests per 15 minutes outside the test environment, so a 429 can come from either limiter. The raw ingress body parser accepts up to 10 MB.
Binding readiness
An active Agent is necessary but not sufficient. Each binding is derived as active or needs_config from its saved fields:
- Slack and Discord: an OAuth connection or integration credential plus at least one channel ID.
- Teams: the same connection requirement plus at least one channel ID and a team ID.
- Email: an organization connection plus a mailbox. Action Agent Studio also generates the binding's encrypted webhook secret.
- Scheduled: a valid recurring schedule and non-empty prompt; it needs no OAuth or credential.
The current Slack, Discord, and Teams ingress handlers route a workspace or tenant only to an oauthConnectionId. A binding that is marked active with only an integrationCredentialId is ready by the generic binding-status rule but does not match current platform ingress. Use an OAuth connection for these three channels.
At ingress, the Agent must still be active, the binding must be active, the event must be enabled, and the scope must match. A matching turn can then fail if the Agent's model, provider credentials, platform credits when applicable, or required tool connection is not ready.
Reply policies
The currently selectable policies are:
| Policy | Behavior |
|---|---|
reply | Send the final assistant text to the inbound channel |
silent | Keep the Agent turn but do not send an outbound reply |
thread | Slack only; send the final text in the inbound thread |
channel_default | Slack only; use the inbound thread when present, otherwise post to the channel |
The database enum also contains dm, but Action Agent Studio does not currently offer it for these trigger channels. Scheduled bindings are forced to silent and never send an outbound channel reply.
Slack ignores the inbound bot's own event before binding matching. Missing channel tokens, bot events, empty text, or a missing workspace connection can therefore produce an acknowledged request without a session.
Scheduled behavior
Action Agent Studio currently saves a recurring schedule as:
- a positive interval in minutes, hours, or days;
- an optional clock time for hour and day intervals;
- a timezone string, intended to be an IANA timezone and defaulting to
UTC; and - a non-empty prompt sent as the user message.
The scheduler runs every minute, claims up to 50 due active bindings per pass, and creates a new scheduled session for each. When a due claim is advanced, the next occurrence is calculated from the claim time, so missed intervals are not replayed one by one. If starting or sending a claimed run fails, ActionFlows restores the prior nextRunAt for a later retry.
Acknowledgement is not execution
Slack, Discord, and Teams return 200 { "ok": true } for several non-execution cases, including bot-message filtering, missing workspace routing, an inactive Agent, needs_config binding, disabled event, scope mismatch, and a caught processing error. Email returns 500 when its accepted processing path throws, but authentication, query-ID, event, and scope rejections can end earlier.
Use Agent sessions, logs, and channel/email delivery to confirm that a turn ran. See Troubleshooting.