Skip to content

Automation triggers

An automation is one trigger paired with one action. Ronja sets automations up during explorations — ask her (for example “Schedule a daily revenue summary every morning at 9 AM”). See Schedule an automation for the walkthrough.

Trigger Workflow action Saved Agent action
Schedule ✓ ✓
Email ✓ ✓
Webhook — ✓ (required)
Table ✓ ✓
Event ✓ ✓
Mailbox — ✓ (required)

The trigger kind is fixed after creation (“Trigger kind cannot be changed after creation.”) — to change it, delete and recreate. The action can be switched on edit, except webhook and mailbox triggers, which stay locked to a Saved Agent. An email or table trigger switches between a workflow and a Saved Agent.

Runs on a cron cadence you set.

Config field Details
Cadence Hourly / Daily / Weekly / Monthly / Custom (5-field cron)
Timezone IANA timezone for the schedule (separate from the reporting timezone)
Minimum interval 1 hour — schedules firing more often are rejected

If a scheduled time doesn’t exist on a given day — a daylight-saving jump skips it — the run fires at the first valid moment after the jump instead of waiting for the next occurrence. When the clocks go back and a time happens twice, the run can happen at both occurrences, so anything a schedule sends or writes outside Ronja should be safe to run twice.

Fires when a matching email arrives at the automation’s private Routable address (⟨org prefix⟩+⟨token⟩@⟨ingest domain⟩).

Config field Details
Routable address Server-generated; Copy and Rotate (rotating immediately invalidates the old address)
Allowed sender domains Mail from any address on these domains can fire the automation
Allowed sender addresses Specific senders permitted in addition to the domain allowlist
  • The sender allowlist is the entire authorization — an enabled email trigger must have at least one allowlist entry, unless it has been deliberately opened to any sender. Keep it tight: the automation acts on content from external senders.
  • Mail from anyone else is turned away and the automation does not run. The refusal is recorded in Run history as Sender refused, so “someone emailed us and nothing happened” is answerable. It is not a failure — it doesn’t count against the automation’s health.
  • Read the refusals as a signal, not a tally. At most one Sender refused entry is recorded per minute, and the entry names the domain of the first refused message in that minute. If several people write in within the same minute, you get one entry and the others leave no trace — so the entry tells you refusals are happening, and roughly when, but not how many or from whom in full. If you need to know who tried, ask the people who expected a reply, or widen the allowlist and watch what arrives.
  • A Refused senders panel sums up the last 30 days on the automation, once something has been refused: how many minutes had a refused sender, how many different sender domains were turned away, when the last refusal was, and the most recent entries. The panel says the window on the line itself. Read the first number as minutes with a refusal, for the reason above — it is not a count of refused emails, and anything older than 30 days drops out of it.
  • Somebody is told. The Automation refused a sender notification is on from the start and goes to whoever created the automation and to your admins, at most once a day per automation. It carries the last 24 hours — minutes with a refusal, how many sender domains, and which ones — and the fix it names is the one on this page: add the sender’s domain to the allowlist. If an address simply attracts strangers, switch Email the owner and admins when a sender is refused off in that panel; the alert stops for that automation only. See Schedule an automation.
  • If the senders are the public — a support address, a supplier inbox — you have two choices: open this trigger to any sender (below), or use a Mailbox trigger, whose sender filter is optional. The difference is what the address is. A mailbox is an address your organization already owns, that Ronja reads and replies to in the same thread. An opened email trigger is the Routable address above — a doorbell that starts a run and never answers the sender.
  • Prerequisite: an admin must first set the org-wide Email-trigger ingest prefix at Governance → Organization rules. Until then the editor shows “Address pending”.
  • Email attachments are saved as Ronja files for the run; the email body is handled as untrusted input. Those files are kept 1 year and then removed from Files — unless you move one into a folder, which keeps it for good. See Limits and retention.
  • A zipped attachment is unpacked automatically while it’s small, and the files inside are available to the run as ordinary attachments. A large or password-protected archive is listed instead — the run can unpack it itself, in full or by naming the files it needs. See Zip archives.

An email trigger can run a Workflow instead of a Saved Agent. Choose it when the email must be handled by code first — every attachment counted, filed or checked — before any AI reads it. The workflow can then hand the email on to a Saved Agent itself.

The workflow takes the email through its inputs. In the automation’s Parameters, type a placeholder into a text input, such as {{ trigger.payload.from }}. The form shows the list of fields under the inputs. {{ trigger.payload }} passes the whole email as one value.

Field What it holds
from The sender’s address
subject The subject line
body The text of the email, cut off at 256 KB (bodyTruncated is then true). An email with only an HTML part gives its HTML
date The date the sender’s email program put on the mail, not the time Ronja received it. Empty when the mail has no date, so a date parameter that takes it fails on that email
attachments A list with one entry per attachment, in the email’s order. Each entry has fileID (the file’s id, or empty — see below), name, contentType, size in bytes, and note
automationRunID The id of this automation run
  • Zip files are unpacked into the list. A zip is listed, and each file it held follows it as an entry of its own. Ronja unpacks a zip only whole: up to 25 files (10 of them images) and 150 MB unpacked, and up to 25 unpacked files per email in all. A bigger zip is listed on its own, with a note saying why it was not unpacked.

  • Very large attachments never arrive. An attachment over 1 GB, or one that takes the email past 1 GB in total, is dropped before the automation runs and is not in the list.

  • Each email runs the automation once. The same email delivered twice runs nothing the second time. A run that fails is not tried again, except one that never started (below). Have the sender send the email again to start a new run.

  • The placeholder must be the whole value. RFQ {{ trigger.payload.subject }} is refused when you save, and so is a field the email does not have.

  • The field has to fit the parameter. A field that no email could fit is refused when you save, with “an email would not fit this workflow’s inputs: …”: the whole email or attachments (or one attachment) in a text, number, date or select parameter, bodyTruncated in a number or date parameter, or an attachment’s size in a date parameter. A parameter with no type takes any field.

  • A long workflow keeps running. A workflow on dedicated compute that is still running after 15 minutes carries on in the background, and the automation’s run history shows its result when it finishes. One that waits more than 13 minutes for a dedicated compute machine never starts, and Ronja tries it once more a minute later.

  • Let the workflow run alongside itself. Leave the workflow’s Concurrency on Allow overlapping runs. On Skip if a run is in progress, an email that arrives while one of the workflow’s runs is still going is turned away, and it is not run again later.

  • An attachment Ronja could not save is still listed, in its place, with no file id and a note saying so. So is one Ronja saved but could not record: its note reads “Ronja saved this file but could not record it, so it cannot be read by id”. Make the workflow stop on an attachment with no file id rather than skip it, so no file goes missing without anyone noticing.

  • The From line is not proof. Nothing on this path checks that the sender is who the From line says, so anyone can claim to be an allowed sender.

  • Hand the email to a Saved Agent as a file. Have the workflow attach the email to the Saved Agent’s run and write the Saved Agent’s instructions itself. Never copy the email’s text into those instructions, or the sender is writing them.

  • The email is kept with the workflow’s runs. A run’s inputs are stored, so anyone who can see the workflow’s runs can read the email.

  • Replying to the sender can loop. A workflow that emails its sender back, when the sender is itself an automatic mailbox, can start a back-and-forth that only the automation’s rate limits stop.

  • To test it, send it an email. Run now has no email to fill the inputs with, so the run fails: “this automation’s inputs take values from the email that triggers it, and this run has none: send it an email, or ask Ronja to test it with a sample email”. Send a real email from an allowed sender to the Routable address, or ask Ronja in a chat to test it with a sample email. Her sample has no attachments.

The allowlist is the normal answer and for most automations it is the only one needed. An address the public writes to is the case it cannot express, so there is one supported way to say it: the automation is opened to any sender. Two switches must both be on, and both start off.

  1. Your organization allows open triggers. An Admin turns this on once, for the whole organization, under Open email triggers on the Organization rules page (sidebar → Governance → Organization rules). The line beside the switch reads Automations may be opened to any sender or No automation may be opened to any sender. It is one of the organization’s email settings, so it can also be set from the API or the CLI — openEmailTriggersAllowed in the mail group, see Change organization settings.

    That section is also the reverse lookup: it counts how many automations are open to any sender — “At least 3 automations are open to any sender” — and links Review them through to that filtered list on the Automations page. It is the only surface that shows the blast radius before the switch is thrown in either direction, and it never claims an all-clear it cannot stand behind: the count covers the automations the Admin reading it can see, and says so when the scan was capped. With the key off it reports what turning it back on would re-open.

  2. The automation itself is opened. Switch Open to any sender on in the automation’s detail page, on the Automations page — or ask Ronja in a Build mode chat in the Ronja app, where she stops to confirm before making the change. A conversation with Ronja in Slack or Microsoft Teams can’t change automations at all. Opening one needs Admin and a person: every machine caller is refused outright whatever role it holds — an automation, a workflow, a Saved Agent, the CLI, and an API token including a personal access token bound to your own admin account — which leaves the switch and a Build mode chat in the Ronja app as the only two ways in. The automation must also carry both of its own rate limits, per minute and per day; the switch offers a per min and a per day box when it has none, and saves them with it. ⚠️ Clearing a rate limit is done in those boxes, not in a chat — a chat can set either limit to a number, but an empty one there reads as leave this setting alone, so Ronja will report the setting unchanged instead of putting the automation back on the organization’s default. Once anyone can fire it, the rate limit is the only bound left on what a stranger can spend, and an organization default is not a decision anybody made about this automation.

While it is open the sender allowlist is not consulted at all, and the automation is allowed to have none. Closing it again carries none of those requirements — but an automation with no allowed senders cannot be closed and left running, since it would then refuse every message it receives. Closing that one also pauses it, which Ronja tells you before you confirm; add an allowed sender in the same edit if it should keep running.

Nothing else about the trigger changes. The rate limits, the credit bounds and the record still work exactly as above, and while either switch is off an unlisted sender is refused and recorded as Sender refused as always.

Fires when JSON is POSTed to the automation’s public Receiver URL.

Config field Details
Receiver URL Server-generated; Copy and Rotate
Signing secret Optional HMAC signing (“Signed (HMAC)” vs “Unsigned — the URL is the secret”); the secret is shown once at creation or rotation
Caps 1,000 runs per rolling 24 hours per automation · 1 MB request body · signed requests must be within a 5-minute timestamp window
  • Without a signing secret, anyone with the URL can trigger the automation — treat the URL as a secret.
  • The editor’s collapsible “How to call this webhook” shows the exact request, including the signature headers and an idempotency key for safe retries.

Fires when a watched table finishes (re)building.

Config field Details
Watched tables At least 1, at most 25 tables, chosen from the automation’s feature
Caps 50 runs per rolling 24 hours per automation (the loop-safety bound)
  • A table trigger cannot run a workflow that writes one of its own watched tables (self-watch loop guard) — but that check can only see the tables the workflow declares it writes, so treat it as a backstop rather than the rule. Watching the table a workflow writes is yours to avoid.
  • Watching the table a workflow reads, and having it run that workflow, is how a table is kept up to date by Python instead of by a query — see Derive a table with Python.
  • A Saved Agent action receives the triggering table’s details; a workflow action runs on its stored parameters.
  • Watching a table counts as depending on it: Ronja refuses to delete a table while an automation watches it, and tells you which automations to detach first. This holds whether the automation is on or paused — a paused one would break the moment you switch it back on.
  • A table built from several inputs rebuilds once, after the last of them has caught up with an upstream change — not once per input — so an automation watching it fires once per upstream change rather than once per input.
  • A Build counts as a (re)build whether or not the pushed data actually changed — so if you push files to a watched table on a schedule, that push is effectively a scheduled trigger, and each one counts against the 50-runs-per-24-hours cap above.
  • A skipped fire catches up. If the workflow or Saved Agent this automation runs is set to Skip if a run is in progress and a fire is refused while one of its runs is still going, the automation runs once more shortly after that run finishes, however many changes arrived meanwhile. A workflow action re-reads its tables live, so that one catch-up run reads every change that arrived; a Saved Agent action receives the most recently changed table only — as in the bullet above — so its catch-up names that table rather than the whole backlog. This is unique to the Table trigger: for every other kind a refused fire is simply turned away. The exception is an automation that changes a table it watches: if its last three runs that actually ran were all such re-runs — a Skipped entry is not a run and is left out of that count — the next refusal is not queued and the Skipped entry says so, so the automation cannot chase its own writes. See Concurrency.

Fires when a named custom event is emitted somewhere in your organization. Events are Ronja’s internal message bus: a workflow can emit one mid-run, or an external system can post one over the API. Every automation that subscribes to that event name fires — one emit fans out to all subscribers in the organization.

Config field Details
Event name The event this automation subscribes to (a lowercase token). Fixed after creation, like the trigger kind
Caps Bounded by a per-organization daily event-run ceiling — a loop-safety bound across all event automations
  • Two ways to emit an event: a workflow emits one during a run (Ronja adds the emit step when you ask her to), or an external system posts one to POST /service-api/v1/event with an API token. Either way, one emit reaches every subscribed automation.
  • The event’s payload is passed to the action as trigger input, and is treated as untrusted — exactly like an inbound email body or webhook JSON. A Saved Agent action reasons over it; a workflow action runs on its stored parameters, except a parameter set to take a field of the event’s payload, which is filled from the event on each run. If the event doesn’t carry that field at all, the run fails, whatever the parameter’s settings. If the field is there but empty or null, the run fails only when the parameter is required and has no default value; otherwise an empty field is passed on as it is, and a null one takes the parameter’s default value when it has one.
  • Because one automation’s action can emit an event that fires another, the per-organization daily ceiling is the guard against a runaway emit → subscribe loop.
  • Run now has no event to fill a parameter that takes a field of the event’s payload, so for a workflow action with such a parameter the run fails: “this automation’s inputs take values from the event that triggers it, and this run has none: emit the event, or ask Ronja to test it with a sample event”. Emit the event, or ask Ronja in a chat to test it with a sample event.

Fires when new mail arrives in a connected mailbox — the shared inbox Ronja reads and replies from as your own address. See Connect a mailbox. One message that matches produces one run of the Saved Agent, seeded with that message.

Binding a mailbox to an automation requires Admin, the same as connecting one.

Config field Details
Watched mailbox The connected mailbox to watch — the picker offers the working ones. Chosen at creation and normally fixed afterwards; the filter stays editable. The one exception is an automation whose mailbox was disconnected — there the picker unlocks so you can point it at a currently connected mailbox
Filters (optional) From these domains · From these addresses · Subject contains · Only messages with an attachment. Up to 50 entries per list
Caps The same per-automation limits as the other push triggers — 1,000 runs per rolling 24 hours and 60 runs per minute by default

The mailbox’s Watched label scopes what the trigger ever sees; the filters narrow it further. If the mailbox has a Watched label set, only mail filed under it reaches any automation on that mailbox — set the label to carve out what Ronja handles at all, and the filters below to split that between several automations. See Watched label.

⚠️ A label that no longer exists is ignored, and Ronja falls back to watching the whole mailbox. A renamed, deleted or mistyped label can’t be matched, and the fallback widens the scope rather than closing it — so an automation with no filters of its own starts firing on every message. Nothing turns red when this happens; if a scoped trigger suddenly starts running on everything, check the label name on the mailbox card first.

Filters are optional — unlike the Email trigger, whose sender allowlist is required unless it has been opened to any sender. A support inbox means unknown senders, so requiring a filter would make this trigger useless for the case it exists for.

  • Leave every filter blank and the automation runs on every new message. That is the normal setup for a shared or support inbox.
  • Filters combine as you would expect: a message must match every section you fill in, and any one entry within a section. Sender domains and sender addresses are one section between them — a message passes if it matches either.
  • Domains match exactly. acme.com matches alice@acme.com but not alice@mail.acme.com — a subdomain is a different domain. List each one you want to admit.
  • Only messages with an attachment narrows what runs, but it bounds nobody — anyone can attach a file. It is not a substitute for a sender filter.
  • Attachments on the triggering message are saved as Ronja files for the run, the same as with the Email trigger, so the automation can read a supplier’s PDF or spreadsheet rather than only being told it exists. Up to 20 files per message, each up to 25 MB, and 100 MB per message in total — anything skipped is spelled out in what the run is given, so a document can be named but absent. A zipped attachment is unpacked while it’s small, exactly as on the Email trigger. Files land in Files like any upload, and are kept 1 year and then removed — unless you move one into a folder, which keeps it for good. See Limits and retention.
  • Changing which mailbox a working automation watches isn’t offered in the product — delete it and create a new one. The API can re-point one (an Admin-only call), and doing so re-arms the automation, so mail already sitting in the new mailbox is not worked through. The exception is repair: if the mailbox was disconnected, the automation’s editor lets you point it at a currently connected mailbox, because a reconnected mailbox is a new one and the automation cannot be switched back on until it is re-pointed.

Ronja shows another warning, at the same moments, when the automation’s Saved Agent doesn’t list this mailbox among its own references. That automation still runs — each run is seeded with the message and can log it, file it to a table, or start something else — but it cannot read, reply to, or triage the mailbox, so an automation meant to answer mail answers nothing. Add the mailbox to the Saved Agent’s references; see References and pre-approved actions.

A mailbox that stops working stops its automations, silently. If the mailbox needs reconnecting — the authorization expired, or the provider check failed — the automations watching it simply stop firing. Unlike a disconnect, nothing is switched off, nothing is marked, and each automation keeps reading Active. If a mailbox automation has gone quiet, check the mailbox’s own card on the Mailboxes page first; Reconnect resumes it, with no re-enable needed.

Only mail that arrives after you enable it fires. Enabling a mailbox trigger does not replay what is already sitting in the inbox — nor does re-enabling one after a pause, which starts from the moment you switch it back on. There is no way to make it work a backlog; ask Ronja to handle a backlog in an exploration instead. Editing a mailbox automation shows the cut-off it is working from, under the Status toggle — “Armed 2026-08-07 09:14 — mail that arrived before then is never picked up” — which is what to check a test message against.

Checking is not instant. Ronja looks at a watched mailbox roughly every couple of minutes while mail is arriving, and less often as it goes quiet — down to every five minutes, then every twenty. First response is minutes, not seconds.

The pace follows the mailbox, not your filters. How busy a mailbox is decides how often Ronja looks at it — not how often any one automation’s filters happen to match. So a narrowly-filtered automation on a busy shared inbox still gets the fast couple-of-minutes pace, and several automations on one mailbox share a single check rather than each adding one.

Ronja looks back only a few hours. Mail that arrives and then ages past that window before a successful check is not picked up afterwards. A long service interruption is the obvious way that happens, but not the only one: it also applies while a mailbox is repeatedly failing to be checked and Ronja is backing off, while its authorization needs reconnecting, and while the mail provider is rate-limiting the account. If a mailbox has been unreachable for hours, treat the mail from that period as needing a person — or ask Ronja to work through it in an exploration.

Disconnecting the mailbox disables the automations that watch it. They are switched off automatically and say why (“Disabled automatically — the mailbox it watched was disconnected. Connecting a mailbox again creates a new one, so edit this automation and point it at a currently connected mailbox before enabling it.”), rather than staying green against a mailbox that no longer exists. Connecting the address again is not enough on its own: a reconnected mailbox is a new mailbox, so open each automation, pick the newly connected mailbox in its trigger, save, and switch it back on. Ronja refuses a plain re-enable while the automation still points at the mailbox you disconnected. Switching one back on re-arms it, so mail that arrived while it was off is not replayed.

Setting Details
Reporting timezone The zone the automation’s Saved Agent action groups days/weeks/months in — separate from the schedule timezone. Blank = organization default. A workflow action that carries a reporting timezone of its own ignores this setting and buckets the same way however it was started; a workflow without one follows it
Concurrency Not a setting on the automation. Whether two runs may overlap is decided by the workflow or Saved Agent the action points at, under its own Concurrency — Allow overlapping runs (the default everywhere) or Skip if a run is in progress. When the action target refuses a fire, the fire is recorded in this automation’s run history as a Skipped run naming the blocking one — neutral, counting neither against the success rate nor towards a failure. Started from anywhere else, the same refusal records no run at all and goes back to the caller. A Table automation that is skipped runs once more shortly after the run in its way finishes, however many changes arrived meanwhile — unless its last three runs that actually ran were all such re-runs (a Skipped entry is not a run and doesn’t count), which is what an automation that changes a table it watches looks like; the entry then says it was not re-queued. No other trigger kind replays a refused fire. Both target pages show the value read-only — ask Ronja to change it. See Concurrency
Pause / resume The on/off toggle on every row and on the detail page; a paused automation ignores its trigger
Run now / Test Manual fire from the row or detail page; Ronja can also dry-run an automation before enabling it. Refused while a run of that automation is already going — including one only waiting, for an approval or an answer — whatever started that run, and independent of the action target’s Concurrency. The refusal is shown in grey in the list or the detail page’s Activity tab and names the blocking run; nothing is recorded. Two manual fires in the same instant cannot both start — the second is refused. ⚠️ A manual fire arriving at the same instant as the automation’s own trigger — any of the six above — still can: that pair is not guarded
Deletion Moves to the 30-day trash and auto-pauses; an admin can restore it

A workflow that stops for a decision part-way through a run automates perfectly well: the run starts normally, sits at Awaiting approval only if it reaches the step that asks, and its approvers get one Review and decide link to the run page. See Mid-run approvals and Approve a workflow run.