--- title: 'Triggers' description: 'Link a provider event to a workflow or an agent in Studio: pick the destination, map the event onto its input, test it, and decide which events belong together.' position: 6.5 --- # Triggers > A **trigger link** starts a workflow or an agent each time a provider event arrives: a new email, a new issue, a new row. You build the link in **Triggers** under Integrations in Studio, with no code unless the mapping needs it. A new link starts switched off, so nothing runs until you have mapped the event and turned it on. A link needs a connected provider, unless its integration needs no connection. If you have not connected one yet, start with [Integrations](/docs/home/features/integrations#connect-a-provider). [Trigger events](/docs/home/features/trigger-events) lists the fields each trigger delivers. ## Create a link Open **Triggers** and click **New trigger**. The dialog, **Link a trigger to a destination**, asks for four things: | Field | What you pick | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------- | | Integration | The providers this workspace has connected, then the ones that need no connection (RSS Feed, Formspark) under **No connection needed**. | | Trigger | The event to watch, from that provider's catalog entry. | | Destination | A workflow or an agent your workspace serves. Open **Select a destination…** to see both kinds in one list. | | Credential | The credential to poll with. `app`, the shared account, is the default. | Some triggers need one more value that scopes the watch to a place. GitHub's triggers ask for the repository, and the link cannot be armed without it. Linear's **New Issue** asks for the **Team** the same way. Google Drive's triggers ask for a **Parent Folder**, which is optional: left empty, the trigger is not scoped to one folder. The dialog labels and explains whichever value the trigger declares. When you pick an agent, the dialog checks what the agent supports. An agent without persistent conversation history and approval pauses gets a warning: **This agent has no persistent conversation history or approval pauses.** If Studio cannot check, it says the capabilities are unverified. Neither warning stops you from creating the link. ## Find a link in the list Each row of the Triggers list names the trigger, its destination and its state. A badge in front of the destination name says which kind it is: **Agent** or **Workflow**. An agent and a workflow can have the same name, so read the badge before you open the row. ![The Triggers screen listing one Gmail link: message-received to the refund workflow, mapped, disabled, never polled, with the integration flagged as having no credential yet.](/images/integrations/triggers.png) _The Triggers list: each link with its state, its mapping and its last poll._ ## Map the event onto the destination The event has its own fields (`from`, `subject`, `threadId`). The destination has its own input: - A **workflow** takes the input its schema declares. - An **agent** takes one field, `message`: the text the agent reads as its turn. It cannot be empty. The mapping editor puts the event and the input side by side. Click a field on the left, then the field it should fill, or drag between their dots. One event field can feed several inputs. **Transforms** (a regex, a template, a default, a date format, JSON parse, a free expression) sit between the two when a value needs shaping. **Auto-map** asks the workspace's model for a first draft, drawn dotted until you accept each line. **Code** shows the same mapping as one expression you can edit by hand. ![The trigger link detail in Studio: source gmail · message-received, workflow refund, credential app, status disabled, and the visual mapping with the event's subject wired to orderId and threadId wired to the correlation key.](/images/integrations/mapping.png) _Two lines drawn, one required field still to fill. The link stays off until it is complete._ The editor names any required input still unmapped. **Test against the sample event** runs the mapping over a sample event and shows the result under **Test output**: what the destination would receive. The sample is a representative event from the catalog, or the first event the link received when the trigger publishes none. **Save mapping** keeps the link's place in the provider's history, so events it already handled do not run again. Then click **Turn on**. ## Decide which events belong together The mapping editor has a **Correlation** card next to the input fields. Wire into it the event field that identifies a conversation, such as Gmail's `threadId`. What the key does depends on the destination. | Destination | The key is a | Left unwired | Wired | | ----------- | ---------------- | ------------------------------------ | -------------------------------------------------- | | Workflow | resume key | every event starts a new run | an event resumes the run parked on that key | | Agent | conversation key | every event opens a new conversation | events with the same key continue one conversation | Click **Test against the sample event** to see what the key evaluates to. Studio shows the value, or warns that the key extracts nothing from the sample. ### On a workflow link: the resume key Your workflow parks a hook with a token and waits. When an event arrives, the box evaluates the key on it and wakes the run parked with that same token, passing it the mapped event. Your workflow must park its hook with the value the key produces, or the event cannot find its run. If no run is parked on that key, the event starts a new run. If the key expression fails on an event, the box rejects the event and no run starts. ### On an agent link: the conversation key The box evaluates the conversation key on the raw event, not on the mapped input. A mapping that leaves the sender out does not lose the conversation with it. A key is usable when it gives a string or a number. The box trims a string first, so `" abc"` and `"abc"` land in one conversation. Anything else (nothing, an empty or blank string, a list, an object, or an expression that fails) still runs the event, in a new conversation, and the link keeps working. When the expression itself fails, the box also logs a warning that names the link. The key belongs to its link. Two links into the same agent never share a conversation, even when their keys give the same value. An agent answers one turn at a time per conversation. An event for a conversation that is still answering waits for that turn to end. After ten minutes of waiting, the box rejects it. A conversation paused on an approval is different: the event waits for the decision, with no time limit. ### On an agent link: wait before replying A customer often sends one thought as several short messages. **Wait before replying** makes the agent hold them and answer all of them in one turn. The section shows on the link once you have saved a conversation key, and the first key you save sets it to 5 seconds. Each new message in the conversation restarts the wait. When the customer has been quiet that long, the agent answers everything they sent. The wait is 1 to 10 seconds. A customer who keeps typing does not hold the answer back for good: 10 seconds after their first message, new messages stop restarting the wait, and the agent answers within one more wait. Leave the field empty to answer each message as it arrives. If you clear the conversation key, the wait goes with it. ## After you turn it on From then on the box polls the provider and handles each new event. Every link polls on the same cadence, 30 seconds by default. The polling is one of the box's [recurring jobs](/docs/home/features/recurring-jobs), so its cadence and last result are on that screen too. A workflow link's runs sit in **Runs** with the others, and **View runs** on the link filters to them. ## What's next - [Trigger events](/docs/home/features/trigger-events): the fields each built-in trigger delivers, and how it decides an item is new. - [Integrations](/docs/home/features/integrations): connect a provider and call it from your code. - [Recurring jobs](/docs/home/features/recurring-jobs): the polling schedule behind every link.