> ## Documentation Index
> Fetch the complete documentation index at: https://docs.maadify.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Triggers

> Start parent agent runs with schedules or webhooks

## What a trigger does

A trigger starts a parent agent run automatically. Every trigger is attached to a **parent agent tenant relationship** (sender to receiver), so the run executes inside the relationship that owns the configured tools and permissions.

Each trigger has:

* A **tenant relationship** that defines which sender drives the workflow and which receiver runs it.
* A **trigger tool** (a schedule or a connector webhook event).
* A **prompt template** that Maadify renders with the trigger payload and sends to the parent agent.
* An **active** toggle that controls whether incoming events are processed.

<Frame>
  <img src="https://mintcdn.com/maadify/K7CT7HZ-nt5ok2U5/images/flows/trigger_node.png?fit=max&auto=format&n=K7CT7HZ-nt5ok2U5&q=85&s=fff10efbe2b212998b2f90c2bb374982" alt="Configured Triggers grid showing trigger cards with sender, receiver, connector, and active status" width="455" height="422" data-path="images/flows/trigger_node.png" />
</Frame>

## Trigger types

Maadify supports two trigger sources:

* **Schedule**: a cron-based job that fires the parent agent on a recurring interval. Schedules are managed by Maadify directly and do not require an external connector.
* **Webhook/Trigger Tool**: a connector event delivered through the configured app (for example, a new email, a new row, or a new form submission). Maadify deploys the listener to the connector.

<Tabs>
  <Tab title="Schedule trigger">
    <Frame>
      <img src="https://mintcdn.com/maadify/X4aEKWAIWIr8YAhZ/images/triggers/trigger_schedule.png?fit=max&auto=format&n=X4aEKWAIWIr8YAhZ&q=85&s=cf66e43758a8108deea40bb4ec31321b" alt="Schedule trigger configuration showing the cron builder and frequency options" width="1719" height="494" data-path="images/triggers/trigger_schedule.png" />
    </Frame>
  </Tab>

  <Tab title="Tool trigger">
    <Frame>
      <img src="https://mintcdn.com/maadify/X4aEKWAIWIr8YAhZ/images/triggers/trigger_field_configurations.png?fit=max&auto=format&n=X4aEKWAIWIr8YAhZ&q=85&s=b89b13b5fc826695cfc6ab8e9a53a8cd" alt="Webhook trigger configuration showing connector property fields and the deployed webhook URL" width="1148" height="332" data-path="images/triggers/trigger_field_configurations.png" />
    </Frame>
  </Tab>
</Tabs>

## Add a trigger

<Steps>
  <Step title="Open the Configured Triggers section">
    From the parent agent canvas, expand **Configured Triggers** and select **Add Trigger**. You need `parent_agents.update` and `trigger_tools.create` permissions on the owning tenant.
  </Step>

  <Step title="Choose a tenant relationship">
    Pick the **sender to receiver** relationship that should own the run. Only active relationships for this parent agent appear.

    <Frame>
      <img src="https://mintcdn.com/maadify/X4aEKWAIWIr8YAhZ/images/triggers/select_existing_relationship.png?fit=max&auto=format&n=X4aEKWAIWIr8YAhZ&q=85&s=0976a5f1ac6aebcb4bc535695ae7a7fd" alt="Tenant relationship picker showing sender and receiver pairings for the parent agent" width="1556" height="431" data-path="images/triggers/select_existing_relationship.png" />
    </Frame>
  </Step>

  <Step title="Pick a trigger tool">
    Select **Schedule** or a connector trigger tool. Toggle **Shared** to browse trigger tools from other tenants you have access to.

    <Frame>
      <img src="https://mintcdn.com/maadify/X4aEKWAIWIr8YAhZ/images/triggers/add_trigger.png?fit=max&auto=format&n=X4aEKWAIWIr8YAhZ&q=85&s=fbd1856997a0543df8661d26df2071b6" alt="Trigger tool grid showing schedule and connector trigger tools with the shared filter toggle" width="1717" height="901" data-path="images/triggers/add_trigger.png" />
    </Frame>
  </Step>

  <Step title="Configure the trigger">
    * For **Schedule**, build the cron expression in the schedule input.
    * For **Trigger Tool**, fill in the connector property fields.
  </Step>

  <Step title="Set the prompt template">
    Select an existing prompt template or create a new one. The template renders with the incoming payload before it is sent to the parent agent (see [Prompt template variables](#prompt-template-variables)).

    <Frame>
      <img src="https://mintcdn.com/maadify/X4aEKWAIWIr8YAhZ/images/triggers/trigger_prompt_template.png?fit=max&auto=format&n=X4aEKWAIWIr8YAhZ&q=85&s=814331296064e5ae5a57a5853fa1c03b" alt="Trigger dialog showing the prompt template selector and editor" width="1122" height="1017" data-path="images/triggers/trigger_prompt_template.png" />
    </Frame>
  </Step>

  <Step title="Save the trigger">
    Select **Create Trigger**. Maadify deploys the schedule and/or event listener.
  </Step>
</Steps>

<Tip>
  You can disable a trigger without deleting it. In the trigger dialog, toggle **Active** off to stop processing incoming events while keeping the configuration in place.
</Tip>

## Edit, disable, or remove a trigger

Each trigger card on the canvas exposes the actions you need.

* **Edit Details**: opens the same dialog used for creation. Use the **Active** toggle to enable or disable the trigger. Editing requires `trigger_tools.update`.
* **Remove Trigger**: deletes the trigger and queues an external cleanup. Removal requires `trigger_tools.delete`.

## How Tool Triggers Run

Tool triggers do not call the parent agent directly. They land in a queue so the run can be retried, traced, and rate-limited.

<Steps>
  <Step title="Receive the event">
    The queues messages in order to be processed by Maadify.
  </Step>

  <Step title="Validate the trigger">
    All active messages will be processed and failed checks are recorded in **Workflow runs** with the reason.
  </Step>

  <Step title="Render the prompt template">
    The worker exposes the request payload to the prompt template under the trigger's tool key, then renders the template with Jinja.
  </Step>

  <Step title="Run the parent agent">
    The worker signs in as the tenant integration user and starts a parent agent run with the rendered prompt and the original payload as context variables.
  </Step>

  <Step title="Record the execution">
    You can see the row immediately in **Workflow runs**.
  </Step>
</Steps>

<Note>
  Events older than five minutes (relative to the event timestamp) are skipped to prevent re-processing stale messages on retries. Failed messages are retried automatically up to the configured `MAX_RETRIES` (default 3) and then archived.
</Note>

## Prompt template variables

Trigger prompt templates use the same Jinja syntax as tool execution payloads. The trigger payload is exposed under a tool-keyed namespace so you can reference any field in the request body.

* **Trigger payload**: `{{ {tool_name}_{tool_id}.<field> }}` — for example `{{ new_email_42.subject }}`.
* **Per-trigger payload**: `{{ {tool_name}_{trigger_id}.<field> }}` — useful when you want to disambiguate between multiple triggers using the same tool.
* **System variables**: `{{ system.current_datetime }}` is always populated with the run start time.

<Tip>
  Use the variable picker in the prompt template editor to insert the right path. The picker also exposes runtime inputs and structured outputs that downstream sub-agents can rely on.
</Tip>

The same payload is stored in the run's context variables, so rules and tool executions further down the workflow can reference `{tool_name}_{tool_id}` and `{tool_name}_{trigger_id}` paths the same way.

## Monitor triggers in Workflow runs

Trigger executions are visible on the **Agent activity** page. Switch the segmented control to **Workflow runs** to see only trigger-driven executions.

The table includes:

* **Id**: the trigger execution id (used for re-runs).
* **Trigger** and **Connector**: which trigger tool fired and which connector delivered it.
* **Sender** and **Receiver**: the tenants involved in the relationship.
* **Date**, **Status** (pending, success, error), and links to view the **Request** and **Response** payloads.

<Frame>
  <img src="https://mintcdn.com/maadify/K7CT7HZ-nt5ok2U5/images/agent-activity/workflow_runs_view_request.png?fit=max&auto=format&n=K7CT7HZ-nt5ok2U5&q=85&s=22216a9c35195135879efd71f61968a7" alt="Workflow runs table showing trigger executions with status, request, and response columns" width="1549" height="741" data-path="images/agent-activity/workflow_runs_view_request.png" />
</Frame>

Each column header opens a filter popover. Select multiple rows and use **Re-run Selected** to enqueue them again.

<Note>
  Re-run skips executions that are still in flight (status pending) and any executions that did not originate from a webhook (for example, schedule-based runs that were dispatched directly).
</Note>

<Frame>
  <img src="https://mintcdn.com/maadify/K7CT7HZ-nt5ok2U5/images/agent-activity/workflow_runs_re-run.png?fit=max&auto=format&n=K7CT7HZ-nt5ok2U5&q=85&s=8434ef8c0fe2b3d4034ebe838d0bf8f1" alt="Workflow runs table with multiple rows selected and the Re-run Selected button" width="1530" height="390" data-path="images/agent-activity/workflow_runs_re-run.png" />
</Frame>

## Permissions

| Action                   | Required permission                               |
| ------------------------ | ------------------------------------------------- |
| View configured triggers | `trigger_tools` read access on the tenant         |
| Add a trigger            | `trigger_tools.create` and `parent_agents.update` |
| Edit or toggle active    | `trigger_tools.update`                            |
| Remove a trigger         | `trigger_tools.delete`                            |
| Re-run workflow runs     | `trigger_executions` access on the tenant         |

<Warning>
  Removing a trigger is irreversible. The cleanup worker deletes the deployed connector listener or cron job, and the trigger row is removed from the database.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Tool Webhook events do not start a run">
    * Confirm the trigger is **Active** and the parent agent is enabled for the receiving tenant.
    * Check **Workflow runs** for an entry with the failure reason (inactive trigger, hidden parent agent, missing webhook).
    * Verify the connector is still authenticated and the deployed listener has not been removed in the connector app.
  </Accordion>

  <Accordion title="Schedule trigger never fires">
    * Open the trigger and confirm the cron expression in the schedule builder.
    * Check that the parent agent tenant relationship is active.
    * Inspect **Workflow runs** for failed schedule executions and review the response body for error details.
  </Accordion>

  <Accordion title="Prompt template renders empty values">
    * Confirm the path uses `{tool_name}_{tool_id}` and matches a field in the request payload sample.
    * Open a recent execution in **Workflow runs** and inspect the **Request** payload to verify the field is present.
  </Accordion>

  <Accordion title="Re-run is disabled or skipped">
    * Re-run only works for completed executions that originated from a webhook. In-flight (pending) rows and direct schedule runs are skipped automatically.
    * The toast message lists which ids were skipped and why.
  </Accordion>
</AccordionGroup>
