Triggers
Triggers define how and when agent sessions are created. A trigger is bound to a specific agent and can fire on a cron schedule, after a deployment, when a matching row is ingested, when a Slack message is posted, when the agent is @mentioned in Slack, or only when manually invoked. Disabled cron triggers are skipped by the scheduler, but manual triggers can always be invoked regardless of the enabled flag.
Service: firetiger.triggers.v1.TriggersService
Resource name pattern: triggers/{trigger_id}
Access: Read-write
Resource type: Trigger
Example flow
Create a manual trigger linked to an agent, then invoke it to kick off a session.
1. Create a manual trigger
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "incident-runbook",
"trigger": {
"display_name": "Incident Runbook",
"description": "Manually invoked to run an incident response playbook",
"agent": "agents/incident-responder",
"configuration": {
"manual": {}
},
"enabled": true
}
}'
{
"trigger": {
"name": "triggers/incident-runbook",
"displayName": "Incident Runbook",
"description": "Manually invoked to run an incident response playbook",
"agent": "agents/incident-responder",
"configuration": {
"manual": {}
},
"enabled": true,
"createTime": "2024-08-01T12:00:00Z",
"updateTime": "2024-08-01T12:00:00Z"
}
}
2. Invoke the trigger
Pass a message that becomes the initial user activity in the new agent session. The response includes the trigger and the name of the newly created session.
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/InvokeTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"name": "triggers/incident-runbook",
"message": "There is an ongoing incident affecting checkout. Run the incident response playbook."
}'
{
"trigger": {
"name": "triggers/incident-runbook",
"displayName": "Incident Runbook",
"description": "Manually invoked to run an incident response playbook",
"agent": "agents/incident-responder",
"configuration": {
"manual": {}
},
"enabled": true,
"createTime": "2024-08-01T12:00:00Z",
"updateTime": "2024-08-01T12:00:00Z"
},
"session": "agents/incident-responder/sessions/ses-abc123"
}
3. Check the session
Use the session name from the InvokeTrigger response to read messages via the Agent Service.
curl -X POST "https://api.cloud.firetiger.com/firetiger.nxagent.v2.AgentService/Read" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{"session": "agents/incident-responder/sessions/ses-abc123", "session_offset": 0}'
Methods
| Method | Description |
|---|---|
| CreateTrigger | Create a new trigger |
| GetTrigger | Retrieve a trigger by name |
| UpdateTrigger | Update an existing trigger |
| DeleteTrigger | Soft-delete a trigger |
| ListTriggers | List triggers with filtering and pagination |
| InvokeTrigger | Manually invoke a trigger to create an agent session |
CreateTrigger
Create a new trigger.
POST /firetiger.triggers.v1.TriggersService/CreateTrigger
Request body
| Field | Type | Required | Description |
|---|---|---|---|
trigger_id |
string | No | ID for the new trigger (alphanumeric, hyphens, underscores). Auto-generated if omitted. |
trigger |
Trigger | Yes | The trigger to create |
Example – cron trigger
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "daily-review",
"trigger": {
"display_name": "Daily Review",
"description": "Runs a scheduled review every morning at 9 AM Eastern",
"agent": "agents/reviewer",
"configuration": {
"cron": {
"schedule": "0 9 * * *",
"timezone": "America/New_York"
}
},
"enabled": true
}
}'
Example – manual trigger
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "incident-runbook",
"trigger": {
"display_name": "Incident Runbook",
"description": "Manually invoked to run an incident response playbook",
"agent": "agents/incident-responder",
"configuration": {
"manual": {}
},
"enabled": true
}
}'
Example – data trigger
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "billing-error-watcher",
"trigger": {
"display_name": "Billing Error Watcher",
"description": "Fires when an error log matches billing-related keywords",
"agent": "agents/billing-responder",
"configuration": {
"row": {
"table_name": "opentelemetry/logs/api-server",
"predicate": "severity = '\''ERROR'\'' AND body LIKE '\''%billing%'\''",
"cooldown": "900s"
}
},
"enabled": true
}
}'
Example – post-deploy trigger
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "post-deploy-smoke-test",
"trigger": {
"display_name": "Post-Deploy Smoke Test",
"description": "Runs smoke tests 5 minutes after the release SHA lands in production",
"agent": "agents/smoke-tester",
"configuration": {
"post_deploy": {
"repository": "acme/backend",
"environment": "production",
"sha": "abc123def456",
"delay": "300s"
}
},
"enabled": true
}
}'
Example – Slack message posted trigger
Fires when any message is posted to one of the listed channels. channels must be a subset of the connection’s allowed_channels (or the connection’s allowlist must be empty, which means unrestricted). include_thread_replies defaults to true when omitted.
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "on-call-listener",
"trigger": {
"display_name": "On-Call Channel Listener",
"description": "Investigates every message posted in #on-call",
"agent": "agents/on-call",
"configuration": {
"slack_message_posted": {
"slack_connection": "connections/slack-workspace",
"channels": ["#on-call"],
"include_thread_replies": true
}
},
"enabled": true
}
}'
Example – Slack agent mentioned trigger
Fires when a SlackHandle is @-mentioned. The handle itself (including the backing Slack user group) is a separate resource managed by SlackHandlesService; the trigger references it via slack_handle and defines the agent + channel scope that responds to mentions.
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/CreateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger_id": "on-call-mention",
"trigger": {
"display_name": "On-Call Mention",
"description": "Triggers the on-call agent when @on-call-bot is @mentioned",
"agent": "agents/on-call",
"configuration": {
"slack_agent_mentioned": {
"slack_handle": "connections/slack-workspace/slack-handles/on-call-bot",
"channels": ["#on-call"]
}
},
"enabled": true
}
}'
Note: a message that mentions both @firetiger and a custom Slack handle in one message fires only the custom handle’s trigger — the default @firetiger investigation response is suppressed to avoid duplicate replies.
Response
{
"trigger": {
"name": "triggers/daily-review",
"displayName": "Daily Review",
"description": "Runs a scheduled review every morning at 9 AM Eastern",
"agent": "agents/reviewer",
"configuration": {
"cron": {
"schedule": "0 9 * * *",
"timezone": "America/New_York"
}
},
"enabled": true,
"createTime": "2024-08-01T12:00:00Z",
"updateTime": "2024-08-01T12:00:00Z"
}
}
GetTrigger
Retrieve a trigger by name.
POST /firetiger.triggers.v1.TriggersService/GetTrigger
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Resource name of the trigger |
Example
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/GetTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{"name": "triggers/daily-review"}'
UpdateTrigger
Update an existing trigger. Use update_mask to specify which fields to modify.
POST /firetiger.triggers.v1.TriggersService/UpdateTrigger
Request body
| Field | Type | Required | Description |
|---|---|---|---|
trigger |
Trigger | Yes | The trigger with name set and updated fields |
update_mask |
string | No | Comma-separated list of fields to update. If omitted, all provided fields are updated. |
Example
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/UpdateTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"trigger": {
"name": "triggers/daily-review",
"enabled": false
},
"update_mask": "enabled"
}'
DeleteTrigger
Soft-delete a trigger. The resource will still be accessible via Get but excluded from List results unless show_deleted is set.
POST /firetiger.triggers.v1.TriggersService/DeleteTrigger
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Resource name of the trigger to delete |
Example
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/DeleteTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{"name": "triggers/daily-review"}'
ListTriggers
List triggers with optional filtering and pagination.
POST /firetiger.triggers.v1.TriggersService/ListTriggers
Request body
| Field | Type | Required | Description |
|---|---|---|---|
filter |
string | No | Filter expression (e.g. enabled = true, agent = "agents/my-agent", associated_resources:"services/api-gateway" for triggers scoped to a Service) |
order_by |
string | No | Field to sort by (e.g. display_name, create_time desc) |
page_size |
integer | No | Maximum results per page |
page_token |
string | No | Token for the next page of results |
show_deleted |
boolean | No | Include soft-deleted triggers |
Example
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/ListTriggers" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{"filter": "enabled = true", "page_size": 25}'
Response
{
"triggers": [
{
"name": "triggers/daily-review",
"displayName": "Daily Review",
"agent": "agents/reviewer",
"configuration": {
"cron": {
"schedule": "0 9 * * *",
"timezone": "America/New_York"
}
},
"enabled": true,
"createTime": "2024-08-01T12:00:00Z",
"updateTime": "2024-08-01T12:00:00Z"
}
],
"nextPageToken": ""
}
InvokeTrigger
Manually invoke a trigger, immediately creating a new agent session. This works for any trigger type – cron, manual, post-deploy, row, or Slack – and works regardless of the enabled flag.
The invoke_payload oneof determines how the agent session is seeded:
message(string, tag 2) — plain text; becomes the initial system activity. Used by cron, manual, row-trigger, and webhook invocations.slack(SlackInvokeContext, tag 3) — populated only by the server-internal Slack event dispatcher after validating the event against the trigger’s scope and the connection’s currentallowed_channels. The server synthesizes a SlackMentionActivity from the context (with a server-resolvedchannel_id) and uses it as the seed. External callers should not populate this variant directly — scope validation rejects out-of-scope channels and pairs ofchannel_name/channel_idare only trustable when the server resolves the ID itself.
POST /firetiger.triggers.v1.TriggersService/InvokeTrigger
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Resource name of the trigger to invoke |
message |
string | One-of | Plain text seed for the session. Use for cron / manual / row / webhook invocations. |
slack |
SlackInvokeContext | One-of | Slack event context. Populated only by the server-internal Slack dispatcher. |
idempotency_key |
string | No | Short-lived dedupe key stamped onto the seed activity. When the Slack dispatcher retries the same event, InvokeTrigger returns the prior session instead of creating a duplicate. Lookup scans recent sessions scoped to the trigger’s agent within a short window (currently 15 minutes) and compares the seed activity’s idempotency_key; no separate dedupe table is used. |
Example
curl -X POST "https://api.cloud.firetiger.com/firetiger.triggers.v1.TriggersService/InvokeTrigger" \
-u "$USERNAME:$PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"name": "triggers/incident-runbook",
"message": "There is an ongoing incident affecting checkout. Run the incident response playbook."
}'
Response
{
"trigger": {
"name": "triggers/incident-runbook",
"displayName": "Incident Runbook",
"description": "Manually invoked to run an incident response playbook",
"agent": "agents/incident-responder",
"configuration": {
"manual": {}
},
"enabled": true,
"createTime": "2024-08-01T12:00:00Z",
"updateTime": "2024-08-05T09:15:00Z"
},
"session": "agents/incident-responder/sessions/ses-abc123"
}
SlackInvokeContext
Server-internal payload for the slack arm of InvokeTriggerRequest.invoke_payload. Populated by the Slack event dispatcher after a verified Slack webhook (message.channels or app_mention) matches an enabled SlackMessagePostedTriggerConfig or SlackAgentMentionedTriggerConfig. External callers should not populate this variant — scope validation is written assuming the dispatcher is the producer.
| Field | Type | Description |
|---|---|---|
slack_connection |
string | The Slack connection under which the event arrived (connections/{id}). Must match the trigger’s configured slack_connection. |
team_id |
string | Slack workspace team id from the event envelope. |
enterprise_id |
string | Slack enterprise id, when the install is on Enterprise Grid. |
channel_name |
string | Channel name with or without a leading #. Required. Normalized to #channel before comparison; validated against both the trigger’s configured channels and the connection’s current allowed_channels. |
thread_ts |
string | Thread timestamp for in-thread events. Empty for top-level events — the server defaults thread_ts to event_ts in that case so the agent’s first reply opens a new thread rather than posting at channel root. |
event_ts |
string | Slack event timestamp. Also used as the message ts when stamping the seed activity. |
user_id |
string | Slack user id of the event originator. |
text |
string | Message text with bot and user-group mentions stripped. |
permalink |
string | Optional Slack permalink to the originating message. |
channel_id is intentionally not a caller-supplied field. The server resolves the channel id from the validated channel_name via a cached conversations.list lookup against the connection’s bot token, and stamps the resolved id onto the seed SlackMentionActivity. Accepting an untrusted channel_id would let a caller pair a valid name with an out-of-scope id and drive agent replies to the wrong channel.
Scope enforcement
InvokeTrigger rejects Slack payloads in the following cases:
| Condition | Code |
|---|---|
The trigger is not a SlackMessagePosted or SlackAgentMentioned variant |
INVALID_ARGUMENT |
slack_connection is set and does not match the trigger’s configured connection |
PERMISSION_DENIED |
channel_name is missing |
INVALID_ARGUMENT |
channel_name is not in the trigger’s configured channels list (when non-empty) |
PERMISSION_DENIED |
channel_name is not in the connection’s current allowed_channels |
PERMISSION_DENIED |
The resolved channel cannot be found via conversations.list |
NOT_FOUND |