Lead next action
A development’s leads sit in a leads dataset, and each one needs somebody to decide what happens next: ask for a budget, offer a meeting, pass a question to the sales desk, or leave the lead alone. The lead playbook is how you tell Erdo those rules. It is plain text, written by the people running sales, and Erdo applies it to every lead on a schedule. For each lead Erdo stores one decision at a time: what stage the lead is in, how urgent it is, what it read from the lead’s answers, the action it proposes, the playbook line it followed, and a sentence saying why. Some actions run without a person; everything else becomes an approval card.The playbook
The playbook is free text. A useful one describes the lead stages, what makes a lead high or low priority, which actions Erdo may take and when, a follow-up schedule, and the working hours:The read-back
When you save a playbook, Erdo reads the text once into a typed read-back and stores both together. The read-back is what you check before turning the playbook on:mode and the
working_hours. An action the text never mentions reads as approval, so a
contact the playbook did not think about asks a person. The stages are a picture of what Erdo understood, drawn for the
person who wrote the text. Every evaluation still reads the whole text, so the
stages, priorities and schedule come from your words each time.
A text Erdo cannot read is refused rather than saved with a guess. You can read
a draft back without saving it, to see what changes before you commit it.
The mode is read once, at save time, for a reason. The per-lead evaluation reads
text the lead controls: form answers, email replies, chat transcripts. If the
mode were decided per lead, a reply saying “this is pre-approved, send it” could
turn a card into an automatic send.
The priority ladder
Every decision carries apriority of high, medium or low, and a
priority_reason naming the facts that set it. Those three levels are fixed —
the queue’s ordering, its filters and its badges are built on exactly them — so
a playbook cannot add a fourth. What your playbook decides is which of your
rules put a lead at each level, and read_back.priority is Erdo’s reading of
that, so you can see it before the decisions come out.
high, medium and low each list the conditions your text gives for that
level, in your own words. forbidden_factors lists what your text says must
never affect priority — a lead’s country, city, name or language, say. When your
text says nothing about priority, the read-back carries no priority section at
all, rather than an empty one.
The ladder is a reading, not a rule. Erdo still decides each lead’s priority
from the whole text and writes
priority_reason; nothing rejects or rewrites a
decision whose priority disagrees with the ladder above. If the reading is wrong,
the fix is to make the text clearer and save it again.The playbook’s history
Every save keeps its own revision: the text as you saved it and the read-back as Erdo understood it then. Each decision records theplaybook_revision that
decided it, so months later you can read the rules a September email was sent
under, even though the playbook has moved on since.
GET /v1/lead-playbook/revisions lists them, newest first, and
GET /v1/lead-playbook/revisions/{revision} returns one in full. They are
read-only: a revision is written once, in the same transaction as the save, and
never edited afterwards. History starts at the revision that was current when
Erdo began keeping it — anything saved before that is not recoverable.
Platform limits
Some limits sit above whatever the text says. Each one the platform applied is listed inlimits, so you can tell the rules you wrote from the ones Erdo
imposed.
An email also becomes a card when the lead has no email address or when the
development has no verified sending domain.
Texts and calls need the lead’s yes. Erdo texts or calls a lead only when
the form they submitted asked whether they may be called and texted, and they
said yes (
consent_given is true on their row). A lead who said no, and a
lead whose form never asked, are emailed instead, or handed to the desk when
Erdo has no email address for them. The check is made when the decision is
taken and again just before the text or call goes out, so a card approved
earlier does not ring a lead whose row no longer says yes. A lead who later
submits the form again and says yes can be texted and called from then on.
How the form asked does not matter, only the answer.
When the text says an action is never, a proposal of it is not filed at all,
not even as a card. The decision is stored as a wait with the reason, and the
lead is looked at again in seven days.
The concierge
A playbook can name one concierge: the voice agent that already answers this development’s website widget, its phone and its texts. Link one and the same person your leads have been talking to is who writes their follow-ups. Three things change when a concierge is linked:- Every draft is written as that concierge. Its persona — the same text the
widget and the SMS replies speak from — says who is writing and how they
sound, and the playbook’s
signature_namesigns the email. The playbook still decides what may be said; the persona never overrides it. - Drafts are grounded in what the development has published. Before each decision Erdo reads the organization’s public knowledge for what this lead has been asking about, so a follow-up can answer a question from last week’s chat instead of repeating the playbook. Facts taken from there are not treated as unsupported figures. A knowledge outage costs the grounding, never the decision.
- Texts and calls become possible to propose. Without a concierge they read
back as
neverand are not filed at all, because nothing is named to carry them out; thelimitssay so. They are still approval-gated with one, and approving one records the decision — statusapproved— which the delivery step then carries out as the concierge.
What the concierge is told to do
A decision about an email, a text or a call carriesagent_instructions in its
action_input: an objective saying what the action is for, and instructions
saying what to say, what not to say, and in what register. For a call that block
is the call brief. For a text the decision also carries sms.body, the message
as the lead would receive it — plain text, at most 320 characters; a longer
draft is dropped rather than trimmed and the downgrade_cause says so.
handoff block at all: it is not work for the desk,
and a card that showed both a desk task and a finished message said two
contradictory things about one decision. handoff.summary belongs to a genuine
handoff, where a person deals with the lead personally; the instructions are
addressed to the concierge that carries a text or a call out. They go through the same figure check as an email body, so an automatic
email whose brief states a price the playbook and the published material do not
becomes a card, and a text card whose brief does says so in its
downgrade_cause. The approval card shows the draft and the brief.
Link a concierge by passing its agent_id when you save the playbook. List the
organization’s concierges with GET /v1/voice/agents or erdo voice agents.
Unlike enabled and daily_contact_cap, agent_id is not kept when you
leave it out: a save with no agent_id clears the link.
The name a lead sees
signature_name is the name your leads meet: a follow-up email is signed and
sent as it, and a call brief opens with it.
It is separate from the concierge’s own name because the two are chosen for
different readers. A voice agent’s name is the label you pick to tell one agent
from another in a list — “Outbound Re-engagement Agent” is useful there and odd
to receive an email from — and the persona written for that agent often
introduces it to leads by a different name again. Set signature_name to the
name the concierge introduces itself by, and the email signature, the From
header and the call brief all agree.
Leave it empty and nothing changes from how the engine has always behaved: the
concierge’s own name signs the draft, and with no concierge linked the draft is
unsigned and the email goes out under the organization’s sending name.
Unlike agent_id, signature_name is kept when you leave it out, like
enabled and daily_contact_cap. Clearing a concierge link is a deliberate
choice a picker offers; a name is free text, and a client that does not know the
field must not be able to strip the name a development signs its mail with. Send
an empty string to clear it back to the concierge’s name.
The name is at most 120 characters and must be a single line — it becomes an
email’s From header.
signature_name in force when it was written,
so a decision that cites a revision can still say which name it went out under.
GET /v1/lead-playbook returns both agent_id (what was saved) and agent
(what it resolves to now). They are the same thing except when the concierge has
been archived, where agent_id is still set and agent is null — that pair
is how you can tell an archived concierge from none at all. An archived
concierge stops texts and calls immediately, without re-saving the playbook.
Everything about a playbook with no concierge works exactly as it always has:
email, wait, close and handoff are unchanged.
Telling the desk a lead needs a person
A handoff is Erdo saying it cannot answer this one — so nothing reaches the lead, and the decision waits as an approval card. A card nobody opens expires after three days, and Erdo then leaves that lead alone for a week. Someone who asked a direct question can therefore sit in silence for ten days while nobody at the desk knows the question was asked.handoff_alert_recipients is what stops that. Every address on the list is
emailed the moment a handoff is filed — not when it is approved, because
approving means somebody has already found the card, and finding it is the
problem. The email says which lead, what Erdo could not answer, why it became a
handoff, and how to reach them, and it links straight to the follow-up queue.
An empty list means nobody is told. That is the default and it is a real
setting, not a gap: Erdo has no fallback audience for this and never emails the
organization’s members instead. A development that has not filled this in gets
the behaviour it has always had, where the card waits in the queue until
somebody opens it.
Addresses are lowercased, de-duplicated and sorted, and at most ten people can
be on the list. An entry that is not an email address is refused and the save
does nothing, rather than being dropped quietly — silently discarding a typo is
how somebody comes to believe they are on the alert list when they are not.
Like signature_name, the list is kept when you leave the field out, so a
client that does not know about it cannot take a development’s desk off its own
alert list. Send an empty list to stop alerting anybody.
Working hours
Nothing Erdo sends goes out outside the playbook’s working hours — an email, a text or a call. Anything decided outside them waits and goes out when the next window opens; it is never failed for being out of hours. A text or a call also has to pass the organization’s own quiet hours and consent rules, and a message those hold back waits in the same way. When the text states no working hours Erdo can read, the default is Monday to Saturday, 08:00 to 19:00, New York time, and the read-back lists that underlimits.
A text and a call follow the lead’s own clock
Your working hours are your development’s — “Monday to Saturday, 08:00 to 19:00, New York time”. An email is sent in those hours, because an email waits in an inbox until the lead opens it. A phone is different: it rings at the moment the message is sent. So for a text and a call, Erdo keeps your days and your hours but reads them where the lead is. A lead in Madrid is texted between 08:00 and 19:00 Madrid time, not between 08:00 and 19:00 in New York — which would have reached them at two in the morning. You do not configure this and there is nothing to set: it follows from the hours you already wrote. Erdo works out where a lead is from the lead’s own record, and never from their name or the language they wrote in:- The timezone recorded when the lead was captured, which is the usual case.
- The country on the lead’s record, where that country keeps one clock.
- The country code of the phone number they gave, if they wrote it with a
+.
The daily contact cap
The daily contact cap bounds how many emails Erdo sends, or puts in front of a person as email cards, in any 24 hours. It defaults to 40 and can be set from 0 to 500. A slot is spent when the email actually goes out, so an email decided on Friday evening takes Monday’s slot rather than Friday’s; one over the cap waits where it is and goes out when a slot opens. The cap stops a first run over hundreds of older leads from emailing all of them in one morning. Handoff cards do not count toward it.How often one lead is contacted
The first thing Erdo tries to find out about a new lead is whether they can be reached at all. A lead who has never answered on any channel — no reply, no call, no chat, no text, no booking — is unconfirmed, and is worked harder and faster, close to when they were captured. The first answer of any kind, on any channel, makes them confirmed for good, and the slower, ordinary pace takes over. Erdo keeps a gap per channel, so an email this morning and a text this afternoon are both possible, while two emails inside the email gap are not:
A proposal inside a channel’s gap is stored as a wait until that channel
reopens. A lead who responded since our last message on a channel can always be
answered at once.
Your playbook can set any of these. Write them in plain language — “while a new
lead has not answered, email at most every two hours and text at most every
hour; once they reply, never email twice in the same week; contact a new lead
thirty minutes after they come in” — and Erdo reads them back to you before any
lead is touched. Erdo will not go below its own minimums (30 minutes between
emails, an hour between texts, three hours between calls, five minutes after a
lead is captured); where your text asks for less, the read-back says so and the
minimum applies. Five minutes after capture is also the default, so a playbook
that says nothing about it gets in front of a new lead as soon as their record
has finished being written.
Two limits hold whatever the playbook says:
- After four messages in a row with no response, another email is always a card, even when the playbook makes email automatic. This does not change while a lead is unconfirmed: four unanswered messages are an answer.
- Working hours, consent, quiet hours, opt-outs and do-not-call are untouched by any of this. Contacting sooner never means contacting outside them, and texts and calls are still always checked by a person.
The sweep
Every 15 minutes Erdo goes through the leads datasets of every organization with an enabled playbook. For each lead it:- Skips test rows, and leads captured in the last 5 minutes, so a capture has finished writing the lead’s record before it is read. Your playbook can set that grace, up to a week; Erdo will not go under five minutes. A new lead does not wait for the next sweep — a capture wakes Erdo directly, and the lead is decided as soon as its grace is up.
- Decides whether the lead needs a new decision. A lead is evaluated when it has never been evaluated, when its row or timeline changed since the last decision, or when the last decision’s revisit time has passed. Nothing else triggers a model call.
- Evaluates the lead against the playbook and stores the decision.
- Sends an automatic email, files a card, or records a wait or close.
Rule citation
An automatic email must quote the playbook line it follows, and Erdo checks that the quote really occurs in the text. Case, line wrapping and list markers do not matter; a paraphrase or an invented rule counts as no rule. The check exists because every evaluation has to propose something. Where the playbook is silent, a model would otherwise fill the gap from general sales sense, and an automatic email that follows no rule you wrote is exactly what the playbook is meant to prevent. So an email that cites no real line becomes a handoff card, and a text or a call that cites none stays a text or a call a person must approve; either way the rationale starts withNo playbook rule was cited:. Gaps in the text therefore reach a person as cards, and the desk adds a line to
the playbook when the situation will come up again. A wait or a close needs no
citation, because neither contacts anyone.
The figure check
An automatic email is checked for figures: prices, dates, times, unit numbers, any number. A figure that does not appear in the playbook, the development’s name or the lead’s own row turns the email into an approval card, with the reason recorded asdowngrade_cause. Links are ignored. The playbook is the only
source of facts an automatic email may state, so a delivery date or a price the
model supplied is checked by a person before it reaches a lead.
Approval cards
An action that needs a person is filed as an ordinary approval request, with the lead as its subject. It appears in the approvals queue with the message, the brief or the desk task in full and the rationale as its context.- Approving records the decision; it does not send. Every approved card —
email, text, call or handoff — lands on status
approved, and a delivery step running every two minutes carries it out. It sends exactly what the card showed: nothing is rewritten between the card and the send. - Before it goes out, the decision is checked against the lead as it is now.
If the lead answered you, was closed or held by the desk, or a newer decision
was filed, the action is
supersededand nothing is sent. The row says which of those it was, inerror, and a decision somebody had approved says so — an approval that does not go out is never dropped silently. A column changing on the lead’s record is not one of these reasons: it makes Erdo look at the lead again, and it does not cancel a step you already approved. - A text or a call is carried out by the concierge, from its own number,
subject to the organization’s consent, opt-out, do-not-call and quiet-hours
rules.
execution_refnames the message or the call that really happened. If the concierge has been archived or unlinked, the actionfailedand says so — Erdo never sends as nobody. - Approving a handoff card records that the desk has taken it. Nothing is sent.
- You can take an approval back until the moment it is carried out:
POST /v1/datasets/{slug}/leads/{lead}/next-actions/undoputs the decision back in front of a person and records who took it back. If the action has already gone out the call is refused rather than pretending to recall it. - Rejecting a text, a call or an email shuts that one channel for this lead for 7 days. Erdo decides again on the next sweep and goes on with the playbook’s other channels, so turning down a text does not also stop the email the playbook sends next. A reply from the lead lifts it early.
- Rejecting a desk task, or letting any card expire after 72 hours, stops Erdo proposing that lead again for 7 days, unless something about the lead changes first: a reply, a call, a new capture, or an edit to its row.
- Editing the playbook withdraws cards nobody has answered yet and decides those leads again. An approved card stays approved: it goes out under the playbook’s current hours and gaps, unless the edit now forbids that kind of contact altogether.
- A newer decision withdraws the older card, so an email that a later evaluation replaced can no longer be approved.
An email alongside a text or a call
A text and a call always wait for a person. An email does not. So a decision to call a lead used to file a card and leave that lead with nothing at all until somebody at the desk acted on it — which may be three days, since a card expires after 72 hours, and then another week of quiet. A decision that needs a person can now carry an email that goes out at once beside it. Erdo writes it in the same evaluation that chose the call, sends it immediately, and the card still waits for you. The lead hears from us within minutes of arriving; the phone call still has a person in front of it. It is one decision, not two. There is still exactly one open suggestion per lead, one card, and one row in the lead’s history — the email rides on it.Whether your playbook sends one
Write it in your playbook text and Erdo reads it back:- “When you decide to call a lead, email them the booking link as well” turns it on.
- “Do not email a lead you are also calling” turns it off.
- Say nothing, and Erdo sends one when your playbook already lets it email a lead without approval, and never otherwise. An unanswered call leaves the lead nothing; an email leaves something they can read and a link they can use. But if you have not given Erdo permission to email a lead unattended, it does not get that permission by attaching the email to something else.
limits when your text asked for
one your playbook does not allow:
What it obeys
Exactly what an automatic email obeys, and in the same words: your daily contact cap, the gap Erdo keeps between two emails to one lead, the ceiling on unanswered messages, your working hours, your verified sending domain, the lead’s consent and opt-out, and the check that stops Erdo stating a price or a date your playbook does not. If any of those says no, the card is still filed — it just says on it that the lead has not heard from us.On the card
The card names the call you are approving and says, above the brief, whether the lead has already been emailed — with the subject and the words that went. You are approving the call, not the email; the email has gone and cannot be recalled. A card that says the email has not gone yet is telling you the lead is still waiting in silence.What it will not do
- It never goes twice. Approving the call carries out the call; the email that already went does not go again, and one that had not gone is dropped — the call is reaching them instead.
- Undo does not unsend it. Taking an approval back puts the call in front of a person again; the email the lead already read stays on the record, and the new card still shows it.
- A replaced decision does not pretend it did nothing. If a reply arrives and a newer decision supersedes this one, an email that already went stays on the record and the concierge is told about it before it calls. One that had not gone is dropped.
accompanying_email:
status is pending (drafted, not sent yet, with error saying what it is
waiting for), sending, sent, failed (a rule said no permanently) or
skipped (the decision moved on first). It is absent on every decision that
carries none.
Hold and close
The sales desk works leads outside Erdo too: calls from its own phones, emails from a colleague’s inbox. Two manual decisions tell Erdo so:- Hold means the desk is handling this lead. It lasts seven days by default, at most 180, and ends early when the lead gets in touch again.
- Close means stop working this lead. Erdo suggests nothing more until the lead gets in touch again.
Statuses
The timeline and the dry run
The timeline is everything the evaluation reads about one lead: the dataset row, the lead’s email addresses and phone numbers, and every entry in time order. Entry kinds arecapture, email, email_reply, sms, call, chat,
booking and suggestion. Every entry is dated when the thing happened, so a
booking carries the moment the lead picked a time and names the meeting itself
in its summary — the meeting is also given on its own as the next or last
meeting in the timing facts. It also carries the timing facts a schedule rule is
matched on, computed by the platform rather than by the model: days since
capture, days since our last message and since the lead’s last reply, how many
of our messages in a row went unanswered, the next or last meeting, and whether
it is now inside working hours. Two readings of the hours are given: the
development’s, which an email follows, and phone_hours, the same hours read
where the lead is, which a text and a call follow. lead_zone beside them says
which timezone that is and how Erdo worked it out — or that it could not, and
your own hours are being used. A source that could not be read is listed under
unavailable, and the evaluation is told that source is unknown.
The dry run evaluates one lead now and returns the decision with the read-back
and timeline it used. Nothing is stored and nothing is sent. Pass a draft
playbook to see what a change would do on a real lead before you save it;
without one, the dry run uses the saved playbook and refuses when none is saved.
Permissions
Reading the playbook, the suggestions, a timeline and the dry run take organization membership. Saving the playbook takes an organization admin. Scoped API keys, the per-end-user credentials, cannot save the playbook or hold and close leads.REST API
A lead is addressed by itscanonical_lead_id UUID or its 22-character lead
reference, as on lead identity. The dataset is addressed by
slug.
Save and enable a playbook:
agent_id that is not a live concierge of your organization is refused with
400 and a message saying which of the three things is wrong: the id is
malformed, the concierge belongs to another organization, or it has been
archived.
List the cards waiting for a person:
action_kind hold, status
recorded and revisit_at set to the end of the hold.
Try a draft playbook on one lead:
MCP tools
MCP clients can read and try the playbook, but cannot change what Erdo does to leads:
Saving or enabling the playbook, and holding or closing a lead, deliberately
have no MCP tool. Enabling a playbook that marks email automatic lets Erdo email
real people without anyone looking, and a hold or close is the desk’s judgement
about somebody it is talking to. A person makes those decisions over REST or the
CLI.
CLI
--json for the raw response.

