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

# Start work when something happens (triggers)

> Wake an agent with a webhook from another app or an event on a connected account, approve the triggers that agents suggest, and see what each event did.

A trigger is a standing instruction to one agent, like a scheduled task, but an event starts it instead of a clock. When the event arrives, the agent starts a run and does what the trigger's instructions say. For work that runs at set times, see [Schedule recurring work](/docs/scheduled).

There are two kinds of trigger:

* **A webhook**: Squad gives you a URL. Another app, such as GitHub, Stripe, Zapier, or your own code, sends events to it.
* **An event in a connected app**: for example a new email in Gmail or a new issue in GitHub, on an account that you connected.

Triggers are on the **Automations** page, on the **Triggers** tab. The **Scheduled** tab next to it has your scheduled tasks.

## Before you start

* To create, change, approve, pause, or delete triggers, you must be the owner or an Administrator. These are the same people who can save scheduled tasks. An Administrator who is limited to some agents manages only the triggers of those agents. See [Invite teammates to your workspace](/docs/teammates#choose-a-role).
* Collaborators and Viewers can open the **Triggers** tab and read the triggers of the agents they can use. They do not see webhook URLs, secrets, the settings of an app event, or what each event contained.
* For an app event trigger, connect the account yourself first. Only accounts that you connected are offered. See [Connect apps](/docs/integrations).

## Add a webhook trigger

<Steps>
  <Step title="Open Triggers">
    Select **Automations** in the sidebar, then the **Triggers** tab.
  </Step>

  <Step title="Start a new trigger">
    Select **+ New trigger**. To add a trigger for one agent, select **+ Add trigger** next to that agent's name.
  </Step>

  <Step title="Choose a webhook">
    Under **What should wake the agent?**, select **A webhook**.
  </Step>

  <Step title="Name it">
    In **Name**, type a short name, for example "New GitHub issue".
  </Step>

  <Step title="Pick the agent">
    In **Agent it wakes**, select the agent.
  </Step>

  <Step title="Write the instructions">
    In **What the agent does with each event**, write what the agent must do with each event. The agent gets these instructions with every event. The event itself is treated as data, never as instructions.
  </Step>

  <Step title="Pick the sender">
    In **Who sends it**, select the app that sends the events. See [Choose the sender](#choose-the-sender).
  </Step>

  <Step title="Add the sender's secret (Stripe, Shopify, Standard Webhooks)">
    For **Stripe**, **Shopify**, or **Standard Webhooks**, paste the secret from the sender into **Stripe signing secret**, **Shopify client secret**, or **Signing secret**. If the sender shows the secret only after you add the URL, leave the field empty and add the secret later on the trigger's page.
  </Step>

  <Step title="Choose the accounts (optional)">
    If your workspace has or had teammates, choose in **Accounts the agent may use while it works**: **Mine and the shared ones** or **Only the shared ones**. See [Choose the accounts of a scheduled task](/docs/scheduled#choose-the-accounts-of-a-scheduled-task). The same rules apply.
  </Step>

  <Step title="Set more settings (optional)">
    Open **More settings** to limit the fields, set **Most runs per day**, or send the result to a URL. See [More settings](#more-settings).
  </Step>

  <Step title="Create the trigger">
    Select **Create trigger**.
  </Step>
</Steps>

The trigger's page opens. It shows the trigger's **URL** and the steps to set up the sender. The trigger shows **On**, or **Needs a secret** when the sender is **Stripe**, **Shopify**, or **Standard Webhooks** and you did not paste the secret yet. Add the secret once the sender shows it. Continue with [Set up the sender](#set-up-the-sender).

### Choose the sender

| **Who sends it** | Use it for | The secret |
| - | - | - |
| **URL only** | Zapier, Make, n8n, forms, and your own scripts | No secret. The URL is the secret, so keep it private. |
| **GitHub** | GitHub webhooks | Squad makes it. You paste it into GitHub. |
| **Stripe** | Stripe webhooks | Stripe makes it. It starts with `whsec_`. You paste it into Squad. |
| **Shopify** | Shopify webhooks | Your app's client secret, from its API credentials. You paste it into Squad. |
| **Standard Webhooks** | Senders that use `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers, such as Clerk and Resend | The sender makes it. It usually starts with `whsec_`. You paste it into Squad. |
| **HMAC signature** | Your own code, when you want each request signed | Squad makes it. Your code signs each request with it. |

<Warning>With **Stripe**, **Shopify**, or **Standard Webhooks**, Squad refuses every request until you add the secret. The trigger shows **Needs a secret** until then.</Warning>

### More settings

* **Only send these fields (optional)**: one field path per line, such as `issue.title` or `data.object.amount`. The agent then gets only those fields. Leave it empty and the agent gets the whole event. The agent can still read the full event when it needs to.
* **Most runs per day**: how many runs the trigger can start each day. Events past the limit are kept, not run. You can run them from the trigger's page. For the default and the highest value, see [Limits and defaults](/docs/limits-and-defaults#triggers).
* **Send the result to a URL (optional)**: an HTTPS address where Squad posts the result of each run. See [Get the result back in your app](#get-the-result-back-in-your-app).

### Set up the sender

On the trigger's page, **Where events come from** shows the **URL**, with **Copy** and **New URL**. Under **Set up the sender**, Squad shows the steps for your sender, with your URL already in them.

For **GitHub** and **HMAC signature**, the secret is hidden. Select **Show** to see it, and the steps then include it. Select **Copy** to copy it.

<Tabs>
  <Tab title="URL only">
    Pick your tool with **Zapier**, **Make**, **n8n**, or **Your own code**, and follow its steps:

    * **Zapier**: add a Webhooks by Zapier action and choose POST. Set the URL to your trigger's URL and the payload type to JSON. Map the fields that your agent needs, and test the step.
    * **Make**: add an HTTP module and choose Make a request. Set the URL to your trigger's URL, the method to POST, and the body type to JSON. Put the fields that your agent needs in the request content.
    * **n8n**: add an HTTP Request node with the method POST. Set the URL to your trigger's URL and send the body as JSON.
    * **Your own code**: send a POST request with a JSON body to the URL. Optional: send an `Idempotency-Key` header, so a request that you retry runs once.
  </Tab>

  <Tab title="GitHub">
    <Steps>
      <Step title="Add a webhook">
        In your repository or organization, open Settings, then Webhooks, then Add webhook.
      </Step>

      <Step title="Set the URL">
        Set the payload URL to your trigger's URL, and the content type to application/json.
      </Step>

      <Step title="Paste the secret">
        Paste the trigger's secret into the Secret field.
      </Step>

      <Step title="Save">
        Choose the events you want, and save.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Stripe">
    <Steps>
      <Step title="Add an endpoint">
        In the Stripe dashboard, open Developers, then Webhooks, then Add endpoint.
      </Step>

      <Step title="Set the URL">
        Set the endpoint URL to your trigger's URL. Choose the events you want, and save.
      </Step>

      <Step title="Copy the signing secret">
        Reveal the endpoint's signing secret and copy it.
      </Step>

      <Step title="Add it to the trigger">
        On the trigger's page, next to **Stripe signing secret: not added yet**, select **Add it**. Paste the secret and select **Save**. Squad shows **Secret saved.**
      </Step>
    </Steps>
  </Tab>

  <Tab title="Shopify">
    <Steps>
      <Step title="Add a subscription">
        In your Shopify app's settings, add a webhook subscription for the topic you want.
      </Step>

      <Step title="Set the URL">
        Set the URL to your trigger's URL and the format to JSON.
      </Step>

      <Step title="Add the client secret">
        On the trigger's page, next to **Shopify client secret: not added yet**, select **Add it**. Paste your app's client secret and select **Save**.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Standard Webhooks">
    <Steps>
      <Step title="Add an endpoint">
        In the sending app, add a webhook endpoint with your trigger's URL.
      </Step>

      <Step title="Add the signing secret">
        Copy the endpoint's signing secret. On the trigger's page, next to **Signing secret: not added yet**, select **Add it**. Paste the secret and select **Save**.
      </Step>
    </Steps>
  </Tab>

  <Tab title="HMAC signature">
    <Steps>
      <Step title="Send a request">
        Send a POST request with a JSON body to your trigger's URL.
      </Step>

      <Step title="Sign the body">
        Sign the raw body with HMAC-SHA256 and the trigger's secret.
      </Step>

      <Step title="Add the signature">
        Put the result in the `X-Squad-Signature` header as `sha256=<hex digest>`.
      </Step>

      <Step title="Avoid double runs (optional)">
        Send an `Idempotency-Key` header, so a request that you retry runs once.
      </Step>
    </Steps>
  </Tab>
</Tabs>

When a sender delivers the same event again with the same delivery ID, Squad keeps it once and runs it once. Squad reads the ID from GitHub, Shopify, and Standard Webhooks headers, from the Stripe event ID, and from an `Idempotency-Key` header.

### Send a test event

On the trigger's page, select **Send test event**. Squad sends an example event shaped like the sender's own events. It wakes the agent for real, and the agent is told that it is a test. The event shows with a **Test** tag under **Recent events**.

**Send test event** works only while the trigger is on.

### Get the result back in your app

When you set **Send the result to a URL (optional)**, Squad posts a JSON body to that URL each time a run ends. No result is sent when the agent was woken but no run started. The URL must start with `https://` and use a public host name.

The body holds the trigger's ID and name, the run's ID and status, the events in the run, and `result`, a short summary of the agent's final reply. See [Limits and defaults](/docs/limits-and-defaults#triggers). Squad signs it in the `Squad-Signature` header as `t=<unix time>,v1=<signature>`. The signature is the HMAC-SHA256 of `<t>.<body>` with the trigger's callback signing secret, in hex. To copy that secret, select **Copy its signing secret** next to **Result sent to** on the trigger's page.

If Squad cannot deliver the result, the event says "The result was not delivered to your callback URL" and the reason.

## Add an app event trigger

<Steps>
  <Step title="Open Triggers">
    Select **Automations** in the sidebar, then the **Triggers** tab.
  </Step>

  <Step title="Start a new trigger">
    Select **+ New trigger**, or **+ Add trigger** next to an agent's name.
  </Step>

  <Step title="Choose an app event">
    Under **What should wake the agent?**, select **An event in a connected app**.
  </Step>

  <Step title="Name it and pick the agent">
    In **Name**, type a short name. In **Agent it wakes**, select the agent.
  </Step>

  <Step title="Write the instructions">
    In **What the agent does with each event**, write what the agent must do with each event.
  </Step>

  <Step title="Pick the account">
    In **Account**, select one of your accounts. Only the accounts that you connected yourself are listed.
  </Step>

  <Step title="Pick the event">
    In **Event**, select the event. The list comes from the app, so each app offers its own events.
  </Step>

  <Step title="Fill in the event's settings">
    Some events have settings, such as a label or a channel. Fill in the required ones. Fields marked **(optional)** can stay empty, and the app then uses its own default.
  </Step>

  <Step title="Choose the accounts and more settings (optional)">
    If your workspace has or had teammates, choose in **Accounts the agent may use while it works**. Open **More settings** for the other options. See [More settings](#more-settings).
  </Step>

  <Step title="Create the trigger">
    Select **Create trigger**.
  </Step>
</Steps>

The trigger's page opens. While Squad asks the app to send the event, the trigger shows **Connecting** and the page says "Squad is asking the app to send this event. This usually takes a few seconds." Then it shows **On**. There is no URL to set up.

On the trigger's page, **Where events come from** names the event, the app, and the account. Below that, it lists the settings that the trigger was saved with, for example the owner and the repository of a GitHub event. Each setting name shows as words, for example **Repo name**. A yes or no setting shows **Yes** or **No**. A setting that you left empty is not listed, because the app uses its own default.

* You cannot change the account or the event later. To listen for a different event or account, create a new trigger.
* If you have no connected accounts, the form says "You have no connected accounts yet. Connect one on the Integrations screen, then come back."
* If the app offers no events, the form says "This app has no events Squad can listen for yet."
* If an event needs a setting that the form cannot show, the form says so and you cannot save. Pick another event, or ask your agent to suggest the trigger with those settings.

## Approve a trigger that an agent suggests

Agents can suggest triggers, for example when you ask for work to be done each time something happens. A suggestion does nothing until you approve it.

```text Ask your lead theme={null}
Each time a new issue opens in our GitHub repository, read it, label it bug, feature, or question, and post a one-line summary in the Squad chat. Suggest a trigger for this.
```

A suggestion shows at the top of the **Triggers** tab under **Suggested by your agents**, with **Waiting for approval**.

<Steps>
  <Step title="Open the suggestion">
    On the **Triggers** tab, select the suggestion. The page says which agent suggested it and why.
  </Step>

  <Step title="Change it if needed (optional)">
    Select **Edit first**, change the fields, and select **Save changes**.
  </Step>

  <Step title="Approve or dismiss it">
    Select **Approve**. To turn it down instead, select **Dismiss**, then **Dismiss** again to confirm.
  </Step>
</Steps>

After you approve it, the trigger is on. Until it is ready, it can show **Needs a secret** (a webhook that needs a pasted secret) or **Connecting** (an app event).

* A webhook suggestion has no URL until you approve it. Then set up the sender. See [Set up the sender](#set-up-the-sender).
* An app event suggestion listens on your own account for that app. If you have not connected one, Squad says "Your own \[app] account is not connected, and approving uses your own account. Connect it first, then approve."
* Unless you chose otherwise with **Edit first**, the trigger's runs use your own accounts and the shared ones.

## Pause, change, or delete a trigger

Open the trigger from the **Triggers** tab, then:

| To | Do this |
| - | - |
| Pause or turn on the trigger | Select the switch next to **On** or **Off**. |
| Change the name, agent, instructions, or settings | Select **Edit**, change the fields, and select **Save changes**. |
| Give the trigger to another agent | Select **Edit**, then pick the agent in **Agent it wakes**, and select **Save changes**. |
| Get a new URL | Select **New URL**, then **Make a new URL**. The old URL stops answering at once. Put the new URL in every app that sends to this trigger. |
| Get a new secret (**GitHub**, **HMAC signature**) | Select **New secret**, then **Make a new secret**. Requests signed with the old secret are refused from then on. Put the new secret in the sender. |
| Replace a pasted secret (**Stripe**, **Shopify**, **Standard Webhooks**) | Select **Replace**, paste the new secret, and select **Save**. |
| Delete the trigger | Select **Delete**, then **Delete trigger**. |

<Warning>Delete cannot be undone. The trigger's event history is deleted with it, and a webhook URL stops answering at once.</Warning>

* If you change **Who sends it**, the secret changes with it. For **GitHub** or **HMAC signature**, Squad makes a new secret. Put it in the sender. For **Stripe**, **Shopify**, or **Standard Webhooks**, the trigger shows **Needs a secret** until you paste the sender's secret. **URL only** has no secret.
* A paused webhook trigger still receives events. It keeps them as "Not run: the trigger was paused", and wakes no one. Turn the trigger on, then select **Run now** on an event to run it.
* When you pause an app event trigger, Squad asks the app to stop sending that event, so events that happen while it is paused usually do not arrive. This does not apply while another trigger listens for the same event on the same account.
* Pausing also stops events that were waiting or being retried. Turn the trigger on, then use **Run now** or **Retry**.
* Squad sends no bell notification or email for suggested triggers, paused triggers, or failed events. Check the **Triggers** tab.
* When you pause an agent, its triggers stay on. Their events wait as "Held while the agent is paused", and Squad delivers them when you resume the agent. See [Add, change, and pause agents](/docs/agents#pause-an-agent).
* When an agent is removed, its triggers pause. Give them to another agent, then turn them on.

## What a trigger run looks like

Each time an event arrives, Squad wakes the agent with the trigger's instructions and the event. A trigger runs one run at a time. Events that arrive during a run wait, and the next run gets them together. For how many events one run can carry, see [Limits and defaults](/docs/limits-and-defaults#triggers).

* On **Runs**, a trigger run has the kind **Trigger**. Its title is "Webhook:" or "App event:" followed by the trigger's name. Under **ACTIVITY**, the **Triggers** filter shows or hides these runs. See [See what your agents did](/docs/runs-and-health).
* On the trigger's page, the line under the name shows the last event and today's events and runs.
* **Recent events** lists the newest events, each with what became of it, such as **Done**, **Agent working**, or **Could not wake the agent**. For every outcome, see [Statuses](/docs/statuses#triggers).

In **Recent events**:

| To | Do this |
| - | - |
| See the run that an event started | Select **Open in Runs**. |
| Run an event that was not run | Select **Run now**. With more than one, select **Run them all now**. The trigger must be on. |
| Try a failed event again | Select **Retry**. It sends all the events of that run again. The trigger must be on. |
| See what the event contained | Select **Payload**. Select **Hide payload** to close it. |

**Run now**, **Retry**, and **Send test event** are not held back by **Most runs per day**. Squad keeps events and their payloads for a limited time. See [Limits and defaults](/docs/limits-and-defaults#triggers).

## Check that it works

* Select **Send test event**. Under **Recent events**, the test event moves to **Done**.
* Select **Open in Runs** on the event to see the agent's run.
* Send a real event from the sender. It shows under **Recent events** with a one-line summary, such as the sender's event name.

## Troubleshooting

| Symptom | Cause | Fix |
| - | - | - |
| The trigger shows **Needs a secret**, and the page says to add the secret. | The sender is **Stripe**, **Shopify**, or **Standard Webhooks**, and no secret is saved. Squad refuses every request until then. | Select **Add it**, paste the sender's secret, and select **Save**. |
| The page says "Squad refused a request" and "The signature did not match the secret." | The sender signs with a different secret. This happens after **New secret**, or when the wrong secret was pasted. | Copy the secret again into the sender, or paste the sender's current secret with **Replace**. |
| The page says "Squad refused a request" and that a header is missing. | The sender does not sign its requests the way **Who sends it** expects. | Check that **Who sends it** matches the app that sends the events, and that the sender has the secret. For an app that does not sign, use **URL only**. |
| The page says "The signature timestamp is too old." | The request was signed too long ago, for example a delivery resent much later. | Send a new event from the sender. See [Limits and defaults](/docs/limits-and-defaults#triggers). |
| The page says "The signing secret is not a valid Standard Webhooks secret." | The pasted secret is not in the form that the sender gives. | Copy the endpoint's signing secret again, in full, and paste it with **Replace**. |
| The page says that requests were refused today because the sender went over the rate limit. The sender gets "Too many events. Slow down and retry." | The sender sent more events than a trigger accepts in a short time. | Slow the sender down, or send fewer, larger events. See [Limits and defaults](/docs/limits-and-defaults#triggers). |
| The sender gets "No trigger answers at this URL." | The URL is old, the trigger was deleted, or it is a suggestion that nobody approved yet. | Copy the current **URL** from the trigger's page into the sender. |
| Events show "Not run: the daily limit was reached". | The trigger started as many runs today as **Most runs per day** allows. | Select **Run now** or **Run them all now**, or raise **Most runs per day** with **Edit**. |
| An event shows "Could not wake the agent", or "Agent woken, no run started". | Squad could not reach the agent, or the agent did not start the run. | Select **Retry**. If the error says "The agent is still being set up on your computer.", wait for the new agent to be ready, then retry. |
| An event shows "Held while the agent is paused". | The agent is paused. | Resume the agent. Squad then delivers the held events. |
| The trigger paused with "The agent this trigger woke was removed." | The agent was removed. | Select **Edit**, pick another agent in **Agent it wakes**, select **Save changes**, then turn the trigger on. |
| The trigger paused with "The account this trigger listens to was signed out. Reconnect it, then turn the trigger on again." | The app account's sign-in expired. | Reconnect the account on **Integrations**, then turn the trigger on. See [Connect apps](/docs/integrations). |
| The trigger paused with "The account this trigger listens to was disconnected." | Someone disconnected the account. | Connect the account again, create a new app event trigger on it, and delete the paused one. |
| The trigger paused with "The app refused this event setup", and a reason. | The app did not accept the event or its settings. | Check the event's settings. **Edit** cannot change them, so create a new trigger with the right settings and delete this one. |
| The trigger paused with "The app did not answer while setting up this event", "The app did not turn this event back on", or "The app stopped sending this event". | The app did not respond, or stopped sending the event on its side. | Turn the trigger on again to retry. |
| An event shows "The result was not delivered to your callback URL". | Your callback URL did not accept the result, or it is not an HTTPS address on a public host. | Check that the URL works and answers, and change it with **Edit** if needed. |
| **Send test event** is greyed out. | The trigger is off. | Turn the trigger on first. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.