Why it attaches to a dataset
Notifications hang off the dataset, not off the pipeline that fills it, and that distinction matters more than it first appears. A real development runs many lead-capture pipelines — one per landing page, per language, per variant. One customer has 25 of them, all writing a single leads dataset. A notification attached to a pipeline covers that pipeline alone, so the day someone launches landing page 26, its leads stop reaching anyone and nothing looks broken. Attaching to the dataset covers every writer, including the ones that don’t exist yet.Setting it up
PUT /v1/dataset-notifications takes the dataset slug and the full recipient
list. The list replaces what was there — send the complete set, not a delta.
GET /v1/dataset-notifications?dataset=<slug> reads the current state back —
recipients, whether it’s on, and the automation implementing it. That state is
read from the automation itself, so there is no second copy of the setting to
drift out of sync with reality.
Passing an empty recipient list turns notifications off.
Turning notifications on never delivers a backlog. Where the dataset currently
stands is recorded at the moment you configure the notification, so only rows
arriving afterwards are announced — including the very first one. Turning
notifications off removes the automation rather than pausing it, for the same
reason: switching back on months later must not dump everything that
accumulated in between into someone’s inbox.
What arrives
Ordinary arrival sends one email per row, so each lead is its own actionable message: who they are and how to reach them first, then what they told the form, then the campaign that brought them. Tracking identifiers — click ids, page URLs, the flags the pipeline stamps on the way in — are join keys for machines and appear nowhere in it. The language they submitted in does appear, because it decides who on the desk can take the call. A burst collapses into a single digest instead of flooding the inbox: either more rows than one run reads, or more messages than one run may send. Every message is tagged with context recording the dataset and which row it concerned —{"kind": "lead_alert", "lead_email": "ana@example.com"}
— so your own product can later show “we alerted the team about this lead” on
the lead itself. This is the only way that link can be made: the recipient is the
sales desk, so nothing about the address says which lead the message was about.
The same lead arriving twice
A lead dataset is not a log. Capture pipelines upsert on the address, so a landing page that asks for an email first and the rest a minute later writes the same lead twice — one row in the dataset, two writes. Announcing that as two leads is wrong, and it is not a rare shape: on one development a quarter of all leads are written more than once, far enough apart that no amount of batching would hide it. The write settles it. Every row records the moment the dataset created it, in a column namederdo_created_at, and a second write to the same row leaves that
moment alone however far the arrival column moves. A notification keeps its
position in that column as well as in the arrival column, so a row created no
later than the point it has already reached is a lead it has announced —
including one that arrived in a burst too large for a single run to read.
On top of that it also remembers which leads it has announced by address, and
what was known about each at the time, which is what covers rows written before
erdo_created_at existed. Either way a row it recognises is not announced again,
and the run result counts it. Two leads that both arrived without an address are
still two leads — an absent address identifies nobody, so neither is suppressed.
Cost
Nothing per run. The automation is a deterministic script fired by an event trigger on the dataset — no LLM, and no polling loop burning tokens to ask whether anything changed. It runs when a row lands and is otherwise idle.Skipping rows you describe
Not every new row deserves an email. Public lead forms attract junk — typo’d addresses that can never receive a reply, gibberish, staff tests — and some desks simply don’t want alerts for rows missing what they need to act. Which rows those are is your call, not the platform’s, so you describe them:skip_when means every new row is announced.
Which column marks arrival
Erdo detects the column recording when a row arrived (submitted_at,
created_at, received_at, and similar) by probing the dataset’s real columns
when you configure the notification. If your dataset names it something
unconventional, pass timestamp_column explicitly.
Detection happens at configuration time on purpose: a dataset with no usable
column is an immediate error you can fix, rather than an automation that looks
perfectly healthy and quietly never notifies anyone.
The recipient list is also the permission
Sending email is a consequential action, so an automation cannot do it unless something authorises it — and an unattended run has nobody to ask, which is why a script that emails on a schedule needs a standing approval granted in advance. A notification does not need one, because the recipient list is the authorisation. Saving a notification records permission for that automation to email exactly the addresses you listed. Remove an address and the permission goes with it; turn notifications off and it is withdrawn entirely. The automation cannot reach an inbox you did not name, even if something goes wrong with the message it composes. This is the difference between a notification and a hand-written script that sends mail. The script names its recipients in code nobody reviewed as a decision about who may be written to, so it is refused until somebody grants it. A notification is that decision, made when you saved it.Limits
At most 10 recipients per dataset — each recipient’s email is one action invocation, and one run may make ten, so a longer list could never be delivered. Sends also count toward your organization’s daily distinct-recipient limit of 50.Related
Sent email
Read back everything that went out, including these alerts.
Automations
The run history of the automation behind a notification.

