> For the complete documentation index, see [llms.txt](https://docs.middle.app/middle-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.middle.app/middle-docs/product/accounts/workflow-triggers.md).

# Triggers

Triggers run workflows based on rules you control

Unless you are using a bulk workflow execution node to initiate your workflows, you will need to set up a trigger to run them automatically. There are three types of triggers: activity-based triggers, scheduled triggers, and real-time workflow API triggers. Triggers are created and managed on your account's **Workflow triggers** page.

## Activity-based triggers

When you want your workflow to run every time a new or updated record is synced, you will want to use an activity-based workflow trigger. When you create this trigger you will need to select which data resource will trigger the workflow. You should select the data resource that corresponds to the workflow you're creating the trigger for. Next, you will select the workflow you want to trigger. You are able to determine if the trigger will only call the workflow when a new record is found, only when a record is updated, or when the record is either created or updated.

Within activity-based triggers you are also able to determine discard criteria and requeue criteria. These criteria are built with [workflow parameters](/middle-docs/product/accounts/workflow-parameters.md) , the same way you build logic in workflows.

![Defining a record type to trigger a workflow](https://932524191-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mks_UuU2atghAuA9bQz%2Fuploads%2FxUQTICdVbwQSBv8JgpGD%2FScreen%20Shot%202021-12-03%20at%204.42.25%20PM.png?alt=media\&token=9c1c4dca-39fb-412d-9b68-e5a8482f431c)

### Workflow inputs

By default, workflow input is constructed automatically. A Foreign Key pointing to the record will be passed into the Workflow as `{"input_object": <ForeignKey>}` .

<figure><img src="https://932524191-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mks_UuU2atghAuA9bQz%2Fuploads%2FFI37hJxv078SDdFVIXCp%2FScreenshot%202026-09-15%20at%2010.48.04%E2%80%AFAM.png?alt=media&amp;token=753c0e51-da40-47f1-8c4d-4076d54b21d0" alt="" width="375"><figcaption></figcaption></figure>

But for workflows with complex inputs, you can use the "Custom workflow input" option and then define the input to be passed into the Workflow using [workflow parameters](/middle-docs/product/accounts/workflow-parameters.md) .

<figure><img src="https://932524191-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mks_UuU2atghAuA9bQz%2Fuploads%2FdJX9xMrOREYkVNrFtzzx%2FScreenshot%202026-09-15%20at%2010.54.30%E2%80%AFAM.png?alt=media&amp;token=55b87ef2-11ea-4fed-966a-12ac02f38bef" alt="" width="375"><figcaption></figcaption></figure>

#### Once vs. Fanout mode

In the case where you just want to trigger a workflow **once**, use either "Apply input automatically" or "Custom workflow input (Once)."

But, for cases where a Workflow needs to be triggered multiple times for a single activity, use "Custom workflow input (Fanout)". Fanout mode lets you define an array, and the selected workflow will be executed once for each element in the array.

For example, imagine we want to invoke a generic "Update CRM" workflow, and this workflow accepts a Foreign Key to a User record type. We know we want to call this every time a user is updated for that user AND any users who claim this user as a "child". We could use the [Construct Array parameter](/middle-docs/product/accounts/workflow-parameters.md) to create a new array, and fill it with the updated user, plus its array of related parents.

<figure><img src="https://932524191-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mks_UuU2atghAuA9bQz%2Fuploads%2FmO3uAtjEQD8d3HEFLo54%2FScreenshot%202026-09-15%20at%2011.17.30%E2%80%AFAM.png?alt=media&amp;token=a533b573-8a89-40be-8ced-020ab823a69a" alt="Screenshot of a Fan Out workflow trigger" width="375"><figcaption><p>Fanout mode, demonstrated.</p></figcaption></figure>

### Prior version

In activity triggers, the "prior version" of the record is available for use in the "variables" dropdown, in Discard, Requeue, and Custom workflow input options.

This can be used to discard updates that don't need to be run against the workflow. For example, imagine you only want to run a workflow if the user's email changes. You can add discard logic to skip running the workflow unless the email has changed.

<figure><img src="https://932524191-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mks_UuU2atghAuA9bQz%2Fuploads%2FIsp22p80jLL7mkDUJV34%2FScreenshot%202026-09-28%20at%208.58.03%E2%80%AFAM.png?alt=media&amp;token=ff472194-426f-4416-afe1-907043e3ed06" alt="" width="375"><figcaption><p>Do not apply the workflow when the "email" field is the same</p></figcaption></figure>

### Discards

Discarding a record in the trigger, rather than filtering in a decision node, is helpful because it's more efficient and faster than relying on a decision node. When a workflow execution is discarded, Middle does not keep a record of why it was discarded. Therefore, you should only discard records on criteria that are foundational to a workflow. Discards are particularly useful for when you are handling a large data resource and only anticipate a sliver of those records making it through the workflow.

### Requeues

Oftentimes, workflows have related records that are crucial to a workflow's completion. For example, say you're running a workflow on sales data, but you also need the client's data. It's possible that Middle has not yet synced the client's data. If that's the case, when the workflow runs it will fail because it doesn't have a synced client record to key into. To keep this from happening, you must construct some logic to check if all needed records are synced before the workflow runs. You are also able to determine a time limit for how long a record will be requeued, while Middle is syncing the missing data, before the record is discarded.

![Generally, when constructing criteria for requeuing a record, you will want to use an
Or to group the If statements, select the related record key, and then select "Does
not exist, or is blank, or is zero"](https://932524191-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mks_UuU2atghAuA9bQz%2Fuploads%2FpGb3kHZkMDQJwkh9lq26%2FScreen%20Shot%202021-10-28%20at%208.15.23%20PM.png?alt=media\&token=a3499504-2d41-4e5c-bc3a-5e1a133e19b2)

### Activity trigger requeues

Every day at 09:00 UTC (1:00 a.m. PST or 2:00 a.m. PDT), a Middle background job is executed to process recent activities in the system and ensure all associated triggers have been correctly executed.

This job checks all app data activity with an activity date timestamp from 3 days ago to 6 hours ago and ensures that all associated triggers are executed. For each trigger the job confirms a successful trigger execution was attempted and completed without error. If no successful trigger execution is found, the trigger is re-executed.

{% hint style="info" %}
If you don't want the requeue job to find a spike of activities recently created, you could adjust the **Apply starting on** date in the trigger to a date after the anticipated spike of activities. This has to be done before 09:00 UTC (when the next requeue job will run).
{% endhint %}

### Replaying triggers

Replay an activity trigger to evaluate a previous record change again, for example after correcting the trigger's conditions or custom workflow inputs.

1. Open **Records** for the app connection, select the record, and open its **Timeline**.
2. Find the activity trigger entry and click **Replay trigger** beside its **Status**.
3. Confirm **Replay trigger**. Middle queues a background task and shows its task ID. You can follow its progress on the **Tasks** page.

If the activity is requeued, the task can finish while the activity is still waiting. Follow the timeline for the final trigger result.

Replay evaluates the source activity using the trigger's current conditions and input mapping, then queues any resulting runs of the workflow's current live version. It keeps the original activity timestamp. Record lookups use current stored values, while the prior record version comes from the original activity when available. Discard and requeue conditions still apply. The requeue time limit is measured from when Middle originally discovered the activity, so replaying an old activity does not restart that time limit.

Refresh the timeline, or enable **Autorefresh**, to see the result. Replay results appear in separate entries labeled **REPLAY**, preserving the earlier trigger history. **Executed** means the trigger processed the activity and queued any resulting workflow runs. Open the workflow execution reports to check what those runs actually did.

Replay is available to users with full account access and organization owners. It supports account triggers and triggers from active modules connected to the account. The trigger must still match the source record's connection, record type, activity type, and **Apply starting on** date. An inactive trigger can be replayed without enabling automatic delivery.

Replaying a trigger rebuilds workflow inputs and can produce zero, one, or multiple runs. Re-executing a workflow instead starts another run with that workflow execution's saved inputs.

## Scheduled workflows

To run a workflow at a specified time, you will set up a scheduled workflow. You have the option to schedule workflows to run hourly, daily, on selected weekdays, or monthly. When you create a new scheduled workflow trigger you will just need to select the schedule and timezone you want the workflow to use. Then, select the workflow you want to run. Scheduled workflows don't have data inputs since there is no record being passed in by the trigger. For scheduled workflows you will want to delete any input in your begin node. Scheduled workflows pair nicely with [bulk workflow executions](/middle-docs/product/accounts/workflow-steps/bulk-workflow-execution.md) . Once you're done setting up your trigger just click save.

{% hint style="info" %}
Say you don't want a workflow to run every day, you can create a decision node on your workflow to look at Now and determine if you want the workflow to run on that given day.
{% endhint %}

## Real-time workflow API

The real-time workflow API allows you to hook up a workflow to run every time it is called with an HTTP API request.

These workflows are subject to certain restrictions, which are explained in a helpful widget on the edit workflow page. Look for the widget titled "\[Not] eligible for real-time workflow API" and hover over it for an explanation of how to make the workflow eligible.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.middle.app/middle-docs/product/accounts/workflow-triggers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
