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

# Arrival notifications

> Email a group of people the moment new rows land in a dataset — declared as a recipient list, not hand-written automation code.

Speed-to-lead is the whole game: a form submission that nobody hears about for
four hours is worth a fraction of one somebody calls back in ten minutes. An
**arrival notification** closes that gap. You name a dataset and a list of
addresses, and Erdo emails those people within seconds of a new row arriving.

You declare *who* and *where*. Erdo owns everything underneath — the automation,
its trigger, the watermark that separates new rows from old ones, and the message
itself. There is no script to write and nothing to keep in sync.

## 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.

```bash theme={null}
curl -X PUT "https://api.erdo.ai/v1/dataset-notifications" \
  -H "Authorization: Bearer $ERDO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "dataset": "2200-brickell.2200-brickell-leads",
        "recipients": ["desk@example.com", "ana@example.com"]
      }'
```

`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**.

<Note>
  Turning notifications on never delivers a backlog. The first run after you
  configure one simply records where the dataset currently stands and emails
  nobody; only rows arriving afterwards are notified. Turning them 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.
</Note>

## What arrives

Ordinary arrival sends **one email per row**, so each lead is its own actionable
message with the captured fields and a subject naming the person. A burst of more
than ten rows in one go is an import rather than genuine arrival, so it collapses
into a single digest instead of flooding the inbox.

Every message is tagged with [context](/sent-email) 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.

## 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.

<Warning>
  Don't build this with a recurring agent or a polling heartbeat. A five-minute
  heartbeat doing this job once cost a customer roughly \$81 in a single week to
  notice one or two leads a day — while also being up to five minutes slower than
  the event trigger.
</Warning>

## 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.

## Limits

At most 20 recipients per dataset. Sends also count toward your organization's
daily distinct-recipient limit of 50.

## Related

<CardGroup cols={2}>
  <Card title="Sent email" href="/sent-email">
    Read back everything that went out, including these alerts.
  </Card>

  <Card title="Automations" href="/automations">
    The run history of the automation behind a notification.
  </Card>
</CardGroup>
