# Audience & Email


Nobody buys from a site they visited once. The people who buy are the ones who left an
email address, got something useful for it, and heard from you a few more times. This
chapter is that machinery on Omumu: the opt-in form that trades a gift for an address, the
sequence that follows up on its own, the invite that gives a few people a week something
free and tells the rest to wait, the quiz that sorts people by what they said, and the inbox
that catches what they write back. Most of it your assistant can set up in a conversation;
all of it is in the admin under *Sales and marketing*.

One rule sits under everything here, so it comes first: **sequence emails go out only
through an email service you connect yourself.** Logins, receipts and access emails always go
out through Omumu. Until you connect Resend or SendGrid, every sequence email is held —
recorded as not sent, never delivered later — and every page in this chapter says so at the
top. Connecting takes a domain you own and three DNS records.

## Concepts

**A contact is a person on your site.** Whoever submits a form, accepts an invite or takes a
quiz with their email gets a user record with no password; buying or being granted a course
makes them a student. They sign in through the one-time link in the access email, or
*Forgot your password?* — there is no separate "contacts" list; *Customers → Users* is
everyone.

**An opt-in form asks for the address.** It has a title, an optional description and trust
line, a submit button, and fields — email always, a name (one field or first and last) and
a phone number if you want them. The form carries its own *tag*, and what it does on
submission is wiring on the form: start an *email sequence*, grant a *course*, then show a
success message or redirect to a page. A form lives on a page: write `[optin-form id="…"]`
on a line of its own in any page, or set it as a designed page's form (the Pages chapter).
Each form counts impressions, unique visitors and submissions per day.

**A sequence is a first email and its follow-ups.** The first email goes after an *initial
delay* from enrolment; each follow-up has its own *send after* — counted from the first
email, not from the previous one, so "day 1, day 3, day 7" means exactly that. Bodies are
written in the editor (or as Markdown through your assistant) and may use merge fields:
`{{first_name}}`, `{{login_link}}`, `{{site_url}}`, `{{resume_link}}` and
`{{email_sequence_cancel_url}}`; square brackets are not merge fields and go out as typed.
Every sequence email carries an unsubscribe link. People get into a sequence through a
form's setting, an invite, an automation's *Start Sequence* step, or a quiz bucket — and the
sequence's page lists those doors, and its members.

**An invite is scarcity you can keep honest.** It gives away a course to *N* people per
*window* — hourly, daily, weekly or monthly, from an opening moment in your time zone — and
when the window's invites are taken, the page turns into a waitlist that is emailed when the
next window opens. Nothing rolls over, nothing is auto-granted; the counter on the page moves
when people act, and there is no countdown clock. Launching makes the whole thing in one
go: a page, a form, three sequences (delivery, waitlist welcome, reopen) seeded in your
language, and the invite — as a *draft*. Its page is a 404 to visitors and its form takes
nothing until you *Go live*, which is refused while any bracketed starter prompt remains on
the page or in the emails.

**A quiz sorts people by their answers.** Questions score towards *buckets*, and a bucket
can tag the person, start a sequence, grant a course, redirect or show a message; the quiz
can ask for an email before or after. It is a page of its own at an address you share, not
part of a course. Building one — questions, answers, points, buckets — is in the Courses &
Content chapter; what it does for your audience is here.

**The inbox is mail to your domain.** With receiving turned on for your Resend domain,
everything sent to any address at it lands in one inbox shared by the site's admins, where
you read, archive, reply and compose. Senders you don't know can be held until you approve
them, and a noisy sender can be bundled into one row.

## Hands-on

### Connect email first

*Integrations → Email*: *Resend* (recommended) or *SendGrid*. For Resend, Mira enters a domain
she owns, picks a region, and gets the DNS records to add at her registrar; once the domain
is verified the banner on every email page goes away and sequences send. Until then she can
build everything below; it simply waits.

### Capture leads with a form

Mira says: *"Make an opt-in form for the free time-audit checklist, start the welcome
sequence when someone signs up, and put it on the About page."*

`omumu_optinform_create` makes the form (name, title, description); `omumu_optinform_update`
wires it — `emailSequenceId`, optionally `courseId` for a free course, `successMessage` or
`redirectUrl`, the button text and a trust line — and `omumu_optinform_add_field` adds a
name or phone field. The page gets `[optin-form id="…"]` through `omumu_page_update`.
`omumu_optinform_list` and `get` read forms back; `omumu_optinform_submissions_list` reads
who submitted, and needs the separate *leads:read* permission because it returns people's
data (the Agent Surface chapter).

In the admin, *Sales and marketing → Opt-in Forms → Create New Opt-in Form* walks four steps —
*Identifier*, *UI & Fields*, *Automation* (the sequence and the course), *After submission*
(message or redirect to a page, or straight to the course) — with a live preview. Each form's
row has *Preview*, *Statistics* (impressions, visitors, submissions and conversion by day)
and *Submissions* (each entry with its fields).

### Write the welcome sequence

*"Write a three-email welcome sequence: the checklist today, a story about my first
automation on day 2, and an invitation to the course on day 5."*

`omumu_email_sequence_create` takes the name, the first email's subject and content (Markdown
is fine), an `initialDelay`, and `followUps` with their own delays (`2d`, `5d`, or ISO
durations). `omumu_email_sequence_update` and `omumu_email_followup_update` change them;
`omumu_email_sequence_get` shows the sequence with its emails and how many people are in it,
how many emails were sent and how many are held; `omumu_email_sequence_list` lists them with
their member counts. Remind the assistant of the merge fields; the tools do not list them.

In the admin, *Sales and marketing → Email Sequences → New Email Sequence*: a name, the initial delay,
the first email, and *Save and create next email* for each follow-up with its *Send after*.
The sequence page lists the emails with their timing and a preview of each.

### See who is in it

The sequence page lists its *members*: name and email, when they were enrolled, how far they
are (not started, "email 2 of 3 sent", or finished), how many emails went out and how many
were held, and the latest open and click. A member expands to their send log, every email with
its status, time and subject. *Remove from sequence* takes a person out of this sequence
only — the way to honour "please stop" without blocking them. The page's *How people get
in* panel names every door: the forms, invites, automations and quiz buckets that enrol into it,
each a link, or says that nothing does.

### Give a few away each week

*"Launch an invite for the pilot group: ten places a week, opening Mondays at nine."*

`omumu_invite_launch` takes the name, a course (or creates an empty one), the quota, the
cadence and opening moment, the zone and the seed language, and returns the draft with its
page, the editor path and the list of placeholders still to rewrite. The assistant rewrites
the page with `omumu_page_update` and the three emails with `omumu_email_sequence_update`,
then `omumu_invite_update` with `active: true` takes it live — refused, with the list, while a
placeholder remains. `omumu_invite_get` and `omumu_invite_list` show the stage (draft, live,
paused), the window ("3 of 10 taken", next boundary) and the waitlist size; `active: false`
pauses it, which also lets its form and sequences be deleted.

In the admin, *Sales and marketing → Invites → Launch Invite* asks for the same things and lands on
the invite's page: the links to its public page, page editor, form and three sequences, *Go
live* once the copy is yours, *Deactivate* and *Activate* later, and a *window history* of
how fast each window sold out.

### Sort people with a quiz

*Sales and marketing → Quizzes* lists them with *View Results*; a quiz's page shows its public address
with a copy button, the questions and the result buckets with their actions, and the email
capture switches (before the quiz, or after it for visitors who are not signed in). *Results*
has the overview, each respondent and their answers, and the free-text answers. Send people
to the quiz from a page, an email or a sales page; they land on a page titled with the quiz.

### Read and answer mail

*Sales and marketing → Inbox* (on plans that include it): *All*, *Unread*, *Read*, *Archived*, search,
and *Compose* to write from your domain. The *Unknown senders* tab has the *Hold unknown
senders* switch; held mail reaches nobody and triggers nothing until you approve the sender,
which also releases everything they already sent. Your assistant reads the inbox with
`omumu_email_inbox_list` and `omumu_email_inbox_get`, but cannot reply.

### What you cannot do yet

Stated plainly: there is no broadcast — to email everyone on a list once, make a one-email
sequence and start it from an automation (the Automations chapter), which is the intended
pattern. There is no contacts page with segments; people are reached through tags and
sequences. Your assistant cannot delete a sequence or an invite, or add follow-ups to an
existing sequence, and deleting a paused invite's form deletes the invite with it. Sequence
timing cannot be relative to the previous email. The inbox cannot be answered over the
connection. And none of it sends until your own email service is connected.

## Reference

### `omumu_email_followup_update`

Updates a follow-up message in an email sequence. All fields except followUpId are optional.

- **Write category:** standard write
- **Access:** requires the `EMAIL_SEQUENCE_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | no | New content in Markdown or QuillDelta JSON |
| `delay` | string | no | New delay from the first email (absolute, NOT relative to previous). Duration string. Accepts ISO-8601 (e.g. PT4H, P1D, P2DT12H, PT0S) or shorthand \<integer>\<m\|h\|d\|w> (e.g. 30m, 4h, 7d, 2w). |
| `followUpId` | string | yes | The follow-up ID to update |
| `subject` | string | no | New subject line |

### `omumu_email_inbox_get`

Retrieves full details of a specific email including headers, body content (text and/or HTML), attachments, and metadata. Use omumu_email_inbox_list first to find email IDs.

- **Write category:** read-only
- **Access:** requires the `EMAIL_INBOX_READ` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `emailId` | string | yes | The email ID to retrieve |

### `omumu_email_inbox_list`

Lists received emails in the inbox with optional filtering by status or search query. Returns email summaries (id, sender, subject, status, date) with pagination. Also returns unread count for quick monitoring.

- **Write category:** read-only
- **Access:** requires the `EMAIL_INBOX_READ` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | number | no | Maximum emails to return per page (default: 25, max: 100) |
| `page` | number | no | Page number for pagination (default: 1) |
| `search` | string | no | Search in sender address, sender name, subject, or recipient address |
| `status` | string | no | Filter by status: UNREAD, READ, ARCHIVED, HELD, or ALL (default: the inbox, which excludes deleted and held email) |

### `omumu_email_sequence_create`

Creates a new email sequence with an initial email and optional follow-up messages. Content can be Markdown or QuillDelta JSON (auto-detected). After creating, link it to an opt-in form via omumu_optinform_update(emailSequenceId) to trigger the sequence when users submit the form. To send a single one-off email to a contact from an automation, create a sequence containing just one message with initialDelay PT0S and start it with the automation's start_sequence action.

- **Write category:** standard write
- **Access:** requires the `EMAIL_SEQUENCE_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | yes | Email content in Markdown or QuillDelta JSON |
| `followUps` | array | no | Array of follow-up messages with delay (offset from the first email, NOT relative to previous), subject, and content. Duration string. Accepts ISO-8601 (e.g. PT4H, P1D, P2DT12H, PT0S) or shorthand \<integer>\<m\|h\|d\|w> (e.g. 30m, 4h, 7d, 2w). |
| `initialDelay` | string | no | Delay before sending the first email. Duration string. Accepts ISO-8601 (e.g. PT4H, P1D, P2DT12H, PT0S) or shorthand \<integer>\<m\|h\|d\|w> (e.g. 30m, 4h, 7d, 2w). Default: PT0S. |
| `name` | string | yes | Sequence name (unique identifier) |
| `subject` | string | yes | Subject line for the initial email |

### `omumu_email_sequence_get`

Retrieves a specific email sequence with all follow-up messages, plus memberCount, sentCount and heldCount. heldCount counts emails not delivered because the site has no sequence email service configured yet. No member identities are included.

- **Write category:** read-only
- **Access:** requires the `EMAIL_SEQUENCE_READ` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sequenceId` | string | yes | The sequence ID to retrieve |

### `omumu_email_sequence_list`

Lists all email sequences for the current site with their follow-up messages and memberCount (how many people are enrolled). No member identities are included.

- **Write category:** read-only
- **Access:** requires the `EMAIL_SEQUENCE_READ` permission

No parameters.

### `omumu_email_sequence_update`

Updates an existing email sequence's properties. All fields except sequenceId are optional.

- **Write category:** standard write
- **Access:** requires the `EMAIL_SEQUENCE_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | no | New content in Markdown or QuillDelta JSON |
| `initialDelay` | string | no | New delay from the subscription trigger. Duration string. Accepts ISO-8601 (e.g. PT4H, P1D, P2DT12H, PT0S) or shorthand \<integer>\<m\|h\|d\|w> (e.g. 30m, 4h, 7d, 2w). |
| `name` | string | no | New sequence name |
| `sequenceId` | string | yes | The sequence ID to update |
| `subject` | string | no | New subject line for initial email |

### `omumu_invite_get`

Gets a single Invite by ID with full config, stage (draft, live, or paused), window state (accepted of quota, next boundary), waitlist size, and placeholders (unrewritten starter prompts still on the invite page or in its delivery, waitlist-welcome, or reopen emails, each with section, field, and excerpt).

- **Write category:** read-only
- **Access:** requires the `INVITE_READ` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `inviteId` | string | yes | The Invite ID |

### `omumu_invite_launch`

Creates a complete Honest Scarcity Invite in one call: a course (or attaches an existing one), three seeded email sequences (delivery, waitlist-welcome, reopen), an opt-in form wired to the course grant and delivery sequence, the Invite itself, the waitlist tag action on the reopen sequence, and the invite page — all wired, but created as a draft: its page answers visitors with a 404 and its form refuses submissions until you take it live. Returns status 'draft', the page URL, the slot editor path, and placeholders (unrewritten starter prompts still on the page or in its emails, each with section, field, and excerpt) so you can customize copy with omumu_page_update and omumu_email_sequence_update before going live with omumu_invite_update (active: true); going live is refused while any remain. Cadence values: HOUR, DAY, WEEK, MONTH. openingDayOfWeek required for WEEK cadence (e.g. MONDAY). openingDayOfMonth required for MONTH cadence (1-31). openingTime format: HH:MM (24h); defaults to 09:00. zone: IANA timezone id (e.g. 'Europe/Oslo'); defaults to Europe/Oslo. seedLanguage: 'nb' for Norwegian Bokmål, 'en' (or omit) for English.

- **Write category:** standard write
- **Access:** requires the `INVITE_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `cadence` | string | yes | Reset cadence: HOUR, DAY, WEEK, or MONTH |
| `courseId` | string | no | Existing course ID to attach; omit to create a new empty course |
| `name` | string | yes | Human-readable name for the Invite (also used as the page headline) |
| `openingDayOfMonth` | number | no | Day of month for MONTH cadence (1-31) |
| `openingDayOfWeek` | string | no | Day of week for WEEK cadence (e.g. MONDAY) |
| `openingTime` | string | no | Opening time in HH:MM (24h); defaults to 09:00 |
| `quota` | number | yes | Slots available per window |
| `seedLanguage` | string | no | 'nb' for Norwegian Bokmål, 'en' or omit for English |
| `zone` | string | no | IANA timezone id (e.g. 'Europe/Oslo'); defaults to Europe/Oslo |

### `omumu_invite_list`

Lists all Invites for the current site with their stage (draft, live, or paused), window state (accepted of quota, next boundary), and waitlist size.

- **Write category:** read-only
- **Access:** requires the `INVITE_READ` permission

No parameters.

### `omumu_invite_update`

Updates an Invite's name, quota, schedule (cadence, opening moment, zone), or active flag. Changing cadence, openingDayOfWeek/openingDayOfMonth, openingTime, or zone recomputes the next window boundary. Raising or lowering quota takes effect immediately in the current window without invalidating existing acceptances. active=true takes a draft or paused Invite live (its page and form start working for visitors), but is refused while the invite page or its delivery, waitlist-welcome, or reopen emails still hold unrewritten placeholders — the error lists each one with where to fix it; rewrite with omumu_page_update and omumu_email_sequence_update, then retry. active=false pauses a live Invite (its page 404s for visitors, its form refuses submissions) and lifts any deletion guards on its form and sequences; deactivating is never refused. Cadence values: HOUR, DAY, WEEK, MONTH. Day-of-week values: MONDAY..SUNDAY. openingTime format: HH:MM (24h). zone: IANA timezone id (e.g. 'Europe/Oslo').

- **Write category:** standard write
- **Access:** requires the `INVITE_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `active` | boolean | no | Whether the Invite is active; deactivating lifts deletion guards on its form and sequences |
| `cadence` | string | no | Reset cadence: HOUR, DAY, WEEK, or MONTH |
| `inviteId` | string | yes | The Invite ID |
| `name` | string | no | Human-readable name for the Invite |
| `openingDayOfMonth` | number | no | Day of month for MONTH cadence (1-31) |
| `openingDayOfWeek` | string | no | Day of week for WEEK cadence (e.g. MONDAY) |
| `openingTime` | string | no | Opening time in HH:MM for DAY/WEEK/MONTH cadences |
| `quota` | number | no | Slots available per window |
| `zone` | string | no | IANA timezone id (e.g. 'Europe/Oslo') |

### `omumu_optinform_add_field`

Adds a new field to collect user information

- **Write category:** standard write
- **Access:** requires the `OPTINFORM_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fieldLabel` | string | no | Display label (e.g., 'Email Address') |
| `fieldName` | string | yes | Internal field name (e.g., 'email', 'firstName') |
| `fieldType` | string | no | Field type: EMAIL, TEXT, PHONE, or HIDDEN |
| `formId` | string | yes | The form ID |
| `placeholder` | string | no | Placeholder text for the input |
| `required` | boolean | no | Whether the field is required |
| `sortOrder` | integer | no | Position in the form (0 = first) |

### `omumu_optinform_create`

Creates a new opt-in form for collecting leads. The form comes with default email and name fields. After creating, use omumu_optinform_update to connect it to an email sequence (emailSequenceId) and/or course (courseId). Embed on a page with [optin-form id="FORM_ID"] on its own line (Markdown, Quill or HTML pages). For templated (SLOT_JSON) pages set the page's optinFormId instead. Forms can also be linked to quizzes as pre-quiz or post-quiz email capture.

- **Write category:** standard write
- **Access:** requires the `OPTINFORM_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `description` | string | no | Description or subtitle. Supports rich text when descriptionEncoding is QUILL_JSON. |
| `name` | string | yes | Internal name for the form (admin use) |
| `title` | string | no | Display title shown to users |

### `omumu_optinform_delete`

Deletes an opt-in form and all its submissions

- **Write category:** standard write
- **Access:** requires the `OPTINFORM_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `formId` | string | yes | The form ID to delete |

### `omumu_optinform_get`

Gets an opt-in form by ID with all its fields. Returns descriptionEncoding (PLAIN_TEXT, QUILL_JSON, or MANAGED_HTML) and trustLine if configured.

- **Write category:** read-only
- **Access:** requires the `OPTINFORM_READ` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `formId` | string | yes | The form ID |

### `omumu_optinform_link_sequence`

Connects an opt-in form to an email sequence so submissions trigger subscription

- **Write category:** standard write
- **Access:** requires the `OPTINFORM_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `emailSequenceId` | string | yes | The email sequence ID to link |
| `formId` | string | yes | The form ID |

### `omumu_optinform_list`

Lists all opt-in forms for the current site

- **Write category:** read-only
- **Access:** requires the `OPTINFORM_READ` permission

No parameters.

### `omumu_optinform_remove_field`

Removes a field from a form by its field ID

- **Write category:** standard write
- **Access:** requires the `OPTINFORM_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fieldId` | string | yes | The field ID to remove |
| `formId` | string | yes | The form ID |

### `omumu_optinform_submissions_list`

Lists submissions for an opt-in form, newest first. Each entry contains the submission ID, timestamp, and the full submitted data (all field values). Returns respondent personal data, so it requires the dedicated leads:read scope (not granted by optinform:read).

- **Write category:** read-only
- **Access:** requires the `LEADS_READ` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `formId` | string | yes | The form ID |
| `limit` | number | no | Maximum number of submissions to return (default 50, max 500) |

### `omumu_optinform_update`

Updates an opt-in form's properties. Use this to connect the form to a course and email sequence, configure the submit button, and set up redirect behavior. Typical funnel setup: create sequence -> create form -> update form with emailSequenceId + courseId + redirectUrl -> embed in page.

- **Write category:** standard write
- **Access:** requires the `OPTINFORM_WRITE` permission

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `courseId` | string | no | Course to grant access to — creates a user account and enrolls them on form submission |
| `description` | string | no | Description. Supports rich text when descriptionEncoding is QUILL_JSON. |
| `descriptionEncoding` | string | no | Encoding for description: PLAIN_TEXT, QUILL_JSON, or MANAGED_HTML |
| `emailSequenceId` | string | no | Email sequence to subscribe users to — triggers the sequence on form submission |
| `formId` | string | yes | The form ID |
| `name` | string | no | Internal name |
| `redirectUrl` | string | no | URL to redirect after submission |
| `submitButton` | string | no | Submit button text |
| `successMessage` | string | no | Message shown after successful submission |
| `title` | string | no | Display title |
| `trustLine` | string | no | Small muted text shown below submit button (e.g., 'No spam. Unsubscribe anytime.') |
