What you can automate
- Run an agent — invoke an agent with a set task, optionally with specific datasets and skills attached.
- Start a conversation — create a fresh conversation and message an agent, so the work shows up as a conversation you can pick up.
- Refresh data — keep a connected dataset up to date on a schedule.
Agent or script
An automation runs one of two ways, and Erdo picks the cheaper one that does the job:- Agent — an AI runs each tick, following your instructions. Use it for work that needs judgement every time: interpreting an anomaly, weighing several metrics, writing a digest someone reads.
- Script — a deterministic check runs each tick with no AI at all. Use it for mechanical work: comparing a number to a threshold, noticing new rows, emailing a templated alert. A script uses one credit per run and no AI, so it can fire the moment data lands without waking an AI on a timer to look.
Recurring tasks use their saved instructions
A scheduled agent can do more than watch for an anomaly. If its saved task says to research prospects, refresh sources, or write a recurring result, each run follows that task and its attached skill: it reads the named catalogue and datasets, looks up the requested web sources, performs the requested writes, and checks the result back before reporting. No attached dataset in the run’s context does not mean the organization is empty. Named sources and web lookups still apply. When a required source, read, write, or checkpoint cannot be completed, the automation reportsattention_needed with the unfinished work instead of claiming normal.
These tasks do not send messages or take other external actions unless the
saved instructions explicitly ask for them and the usual approval rules allow
it.
Platform-managed default agent monitors refresh their instructions before each
run, so a monitoring correction reaches the next pass. Your instruction edits
keep their ownership. The schedule and approval rules continue to apply.
Daily Monitor findings
Before diagnosing a client’s advertising performance, the Daily Monitor reads that client’s decision record, explicitly naming itsorganization_slug on every read.
Its attention-feed read can also name the client’s organization_slug; a bounded
read reports feed_complete: false when records remain. An empty HQ record, an
authorization failure, or an incomplete scan cannot establish that the
client made no paid-media changes.
Scheduled heartbeat monitors load a fresh, organization-scoped standing paid-media decision snapshot before their first model request. A failed read stops the run with an explicit context error; incomplete coverage is reported as unknown. Paid-media monitors read standing decisions separately from recent changes. A standing
measurement rule remains relevant even when it was authorized before the comparison window:
for example, a fraud-tainted period excluded by an existing decision must stay out of the baseline.
Reports state the comparable windows, outcome counts and remaining uncertainty. A non-zero
advertising conversion-rate decline alone needs at least five baseline outcomes and five expected
outcomes at recent traffic before escalating; a large percentage on a tiny sample remains a watch.
Independently verified failures and the existing zero-stretch rule remain incidents. Equal totals
from ads and captured leads alone do not prove healthy attribution or better lead quality. Some leads arriving or one successful probe also cannot rule out partial capture loss on another path.
Routine successful checks, unchanged holds and checks below the traffic floor remain in the
run summary. They do not need an inbox item. When verified evidence disproves a monitor’s
older warning, the monitor clears that warning with its evidence; publishing a correction alone
does not clear it. Missing data alone is never evidence that an incident recovered. Read-only investigation is automatic follow-up, not a Yes/No approval; a proposed answer is reserved for a concrete action or preference requiring your decision.
A material improvement can produce a quiet digest when matching complete periods, fresh data,
and sufficient observations support it: at least three complete days and five outcomes in each
period. Outcome counts must rise by at least 50% and five outcomes; acquisition cost must fall
by at least 25% with consistent spend and outcome coverage. These reporting thresholds do
not establish statistical significance. The digest gives the values and sample sizes and uses a
stable metric/resource/change identity so unchanged positives are not announced every day.
Higher lead counts alone do not establish better lead quality.
Regressions keep their existing lifecycle: the monitor re-confirms an open finding under its
existing key while it persists and resolves it with evidence when it clears. A zero stretch
requires complete days with at least three expected outcomes from the relevant post-change
baseline; an ordinary zero day is not an urgent alert.
Choose the agent for recurring work
Agent automations default toerdo.heartbeat-executor, which checks for changes
and reports findings. For a recurring task that must research sources, write
results and verify a saved checkpoint, select erdo.workflow-executor directly.
It performs the task on each run without a monitoring agent delegating it first.
Set agent_key when creating an agent automation over the API or MCP, or change
an existing automation with PATCH /v1/heartbeats/<id>:
agent_key. Omitting
the field keeps the existing agent. Changing only the agent preserves the
schedule, attached datasets and skills, instructions, model and run history.
The supported selections are erdo.heartbeat-executor and
erdo.workflow-executor; scripted automations have no agent to select.
Approvals and dataset access still apply to every run.
Escalating: a script that calls in an agent
Most days a check finds nothing. Refunds are normal, the pipeline moved as expected, nobody churned. Running an agent every morning to establish that is paying for judgement on the days there is nothing to judge — and picking the script instead means that on the one morning something is wrong, all you get is the threshold that tripped. You don’t have to choose. A script can hand its finding to an agent, and only on the runs where it matters:- It doesn’t wait. An agent takes minutes; the script gets the conversation it started and moves on. So the brief has to say where the agent should put its answer — email this address, write to that dataset, update that page. “Investigate the spike” with no destination produces work nobody sees.
- Put everything in one brief. A script run escalates once. If two checks trip on the same morning, describe both in the same brief rather than starting two agents.
- Approvals still apply. Escalating is not a way around the review queue — anything the agent does that would normally need approval still needs it, and a run that hits one waits there for a person. If the escalation should complete unattended, grant a standing approval for what it will do (run the action once in a conversation and choose always allow) before you rely on it.
Triggers
- Schedule — run on a recurring cadence (e.g. every morning, every Monday).
- Webhook — run when an external system POSTs to the automation’s URL; the payload is handed to the agent.
Run once at a time, or stop after one
A schedule can carry two optional bounds, both RFC3339 instants:run_atmakes the automation a one-off. Nothing runs before that time; it runs once at or after it, and then it stops for good. A fired one-off can’t be re-enabled or edited. Create a new automation if the work has to happen again.ends_atkeeps the normal schedule and stops it after that time. No run starts later thanends_at.
run_at for work that belongs to a date, such as rolling trial budgets back
on the 19th. Don’t write a recurring automation whose instructions check
whether the date has arrived. That version runs, and is billed, on every tick
until the date, and each run that finds nothing to do still adds a thread to
your feed. One deadline check polling every five minutes runs about 2,000 times
a week to do its job once.
erdo_create_heartbeat / erdo_update_heartbeat and
POST / PATCH /v1/heartbeats, and every read-back returns them. On an edit, an
omitted bound keeps its stored value. Changing a bound never pauses or resumes
the automation, so a paused automation stays paused when you move its date.
Refreshes pause themselves when nobody’s looking
A managed client’s direct manager activity counts as human engagement for its refresh: a manager dashboard visit can keep the refresh running even when the client workspace’s own activity stamp is older. A manager sign-in also resumes refreshes Erdo auto-paused in directly managed client orgs, re-arms their schedules, and clears the pause notices. Explicitly disabled or user-paused jobs are never changed. A sign-in in the refresh’s own organization does not replace output viewing; this exception applies only to directly managed client organizations. Agent/query activity and recursive or unrelated organizations do not count. A scheduled data refresh exists to keep something you look at fresh — a dashboard, a published page, the dataset itself. When two weeks pass without anyone viewing what a refresh feeds, Erdo pauses its schedule rather than keep spending runs on data nobody reads. The automation shows as Auto-paused under Activity, the workspace owner gets a one-time email, and nothing is deleted: the dataset, its history, and the automation’s configuration all stay exactly as they were. Resuming is automatic the moment the output matters again. Open the dashboard it feeds — or a real visitor lands on the published page — and the schedule picks back up, with the stale data refreshed right away. Turning the automation back on from Activity, or running it manually, resumes it too. Its pause notice clears when the automation is active again. A manual Run now request counts as engagement even when it joins an existing refresh run. Turning a schedule on alone does not start a new two-week activity window; current views, manual runs and eligible manager activity determine whether it stays active. Only scheduled data refreshes pause this way. Automations that act directly — sending alerts, archiving email, filing reports — are not paused for lack of views. Erdo also exempts the acting refreshes it installs for you: the live page health monitor raises alerts, and the experiment measurement loop can propose or apply changes, so neither stops because its dataset is unviewed. A custom data-refresh script can still auto-pause after two weeks without a view, even if it sends an alert; opening its dataset or running it manually resumes it.Notification emails
When an automation emails you — a new lead landed, a threshold was crossed, a weekly summary is ready — Erdo composes the message rather than the automation writing raw markup. You get the same styling as every other Erdo email: a heading, the facts as label/value rows, a button through to the page or dashboard the alert is about, and addresses and links that are clickable, so you can reply to a lead straight from the notification. Every message also carries a plain-text version, so it stays readable in a client that blocks HTML and in a forwarded copy. This holds however the alert is built. Erdo will often set an alert up as a small deterministic script — it fires the moment the data lands and costs nothing to run, unlike an agent waking on a timer to check — and those scripted alerts are styled exactly like the ones an agent sends. When the same kind of email goes out from several places — one lead alert across a handful of campaigns, say — Erdo can save it as a reusable template in your Knowledge: the layout is written once, with placeholders for the details, and each send fills in the data. Editing the template updates every automation that uses it, and the values are still escaped and given a plain-text version automatically, so a template is as safe as a one-off message.When your credits run out
Automations that use AI need credits to run. When your workspace’s balance runs out, background automations start failing instead of running — and because credits are shared across the workspace, one empty balance affects every automation that needs them, not just one. You hear about it immediately, not after it has quietly failed for a day: the first failure opens a single item in your Activity feed naming the automations affected, and your workspace’s admins get one email with the same facts and a link to add credits. It’s one item and one email for the whole episode — a balance that stays empty doesn’t re-alarm on every failing run — and both clear themselves as soon as a run succeeds again after a top-up. The one thing to act on: if nobody adds credits within 24 hours, Erdo disables the failing automations so they stop burning through retries. Nothing is deleted — re-enable any of them from Activity once credits are added, and it picks up where it left off.Suggestions Erdo makes for you
While an agent works through your data it sometimes notices something worth watching every day — a metric that drifts, a table that stops filling, a spend line that only matters once it moves. Rather than arming a schedule you never asked for, it files the idea as a suggestion. Suggestions live in their own collapsed group at the top of the automations list under Activity → Automations, headed with a count so you can tell at a glance whether there is anything new. Nothing runs, nothing costs credits, and nothing sends email until you open one and say yes. Opening a suggestion shows exactly what it would do: the instructions the agent wrote, the datasets it would read, and the interval it proposes. Change any of them before you activate — what you approve is what runs, not the original draft. Activating turns the suggestion into an ordinary automation that behaves like one you created yourself, schedule and all — it appears in the list below, runs on the schedule you picked, and an agent asked later what already watches that data will find it. Dismissing removes the suggestion. If there are no suggestions, the group isn’t there.Editing an automation
Change an automation in place without recreating it — rename it, move its schedule, pause it, or replace what it does (an agent automation’s instructions, a scripted one’s body). Its history and its place in your workspace carry over. From the terminal:erdo_update_heartbeat), and in
the app.
You can replace an agent automation’s instructions without resending its name or
description. Omitted fields keep their current values, including its schedule,
next run, enabled state, model and attached skills. An explicit name or description
changes that field. When replacing instructions through the job API, an explicit
skill list replaces the other attached skills; an empty list removes them.
Choose where an agent automation posts
By default, each agent run creates a new automation conversation. You can have the automation post into its persona’s direct conversation with the owner, or into an existing conversation the owner can access. Direct conversations are created the first time a run needs one. Setpersona_id to choose the speaker;
when omitted, a heartbeat created from a persona-owned template uses that
persona. Scripted automations cannot target agent conversations.
Create an agent heartbeat with a direct target through MCP or POST /v1/heartbeats:
thread_id instead of
conversation. Update either target in place with erdo_update_heartbeat,
PATCH /v1/heartbeats/<id>, or the CLI:
conversation: "new" restores
the default of creating a fresh automation conversation. The target is returned
by automation readback as conversation, thread_id, and persona_id.
Keep an eye on things
Everything an automation does is visible under Activity:- Runs — the execution history, with status, timing, and any errors.
- Feed — a live log of what’s happening across your workspace: agent runs, data refreshes, approvals, and new knowledge.
You’re still in control
Automated runs follow the same rules as interactive ones: consequential actions still go through approval, and new knowledge still lands in Review. An automation can do the work unattended without being able to act outside the bounds you’ve set. Unattended runs consume approvals rather than asking for them. Nobody is watching a 6am run, so it never raises a card — a scheduled automation that raised one per tick would fill your queue with asks about work that had already stopped waiting. Instead it looks for a standing approval covering what it is about to do, and fails the run with a message naming the action when it finds none. Grant one by running the action once in a conversation and choosing always allow, or by creating a policy against the automation directly. Sending email is one of these actions, including from a script’s ownactions.invoke('erdo', 'send_email', …). If you want mail sent on arrival
rather than on a schedule, prefer an arrival
notification: its recipient list is the authorisation,
so there is nothing separate to grant and nothing that can quietly widen.
Scope a heartbeat edit
When editing a heartbeat found through another organization-owned resource, sendexpected_organization_id with the existing heartbeat update request. The edit
still requires normal resource permissions and refuses a different current owner
before changing the job, instructions or trigger. Omitting this optional
precondition keeps the normal direct-edit behavior. Workstream loop reuse supplies
it automatically, and workstream wakes check current job ownership before bringing
a schedule forward, so a stale monitoring link cannot edit or wake a transferred
heartbeat in another organization.
A declaration that cannot safely resume remains paused and raises an operator error. Other eligible automations resume independently; one invalid declaration does not hold the whole workspace paused.
Organization activity reads only paused automation identifiers in bounded pages. Jobs are checked again before resuming; activity does not load unrelated automation scripts. A job that becomes eligible behind an in-progress page is considered on the next activity event.
