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

# Email

> Send and receive email from Momentic-provisioned inboxes inside **JavaScript** steps.

<Info>
  **Prerequisites**: A permanent inbox provisioned in **Settings > Email
  inboxes**, or an ephemeral inbox created at runtime with
  [`email.create`](#email-create).
</Info>

Email runs inside the **JavaScript** step's sandbox via the global `email`
object. Momentic-provisioned inboxes end in `@usemomentic.com` or
`@gomomentic.com`.

## `email.create`

Provision a fresh ephemeral inbox at test runtime. The returned inbox is
auto-deleted by Momentic after **24 hours**. The lifetime is fixed and not
configurable from test code.

Use this when each run needs a clean inbox (signup flows, magic-link logins,
password resets) and you don't want to share a permanent address across parallel
runs.

```ts theme={null}
const inbox = await email.create();
// inbox.email     -> "mom-1a2b3c4d5e6f@gomomentic.com"
// inbox.prefix    -> "mom-1a2b3c4d5e6f"  (use as `inbox` in fetchLatest/fetchAll)
// inbox.expiresAt -> Date  (when Momentic will delete it)

setVariable("INBOX_EMAIL", inbox.email);
setVariable("INBOX_PREFIX", inbox.prefix);
```

Then drive your app's signup flow with UI steps using `{{ env.INBOX_EMAIL }}`,
and in a later **JavaScript** step fetch the verification email:

```ts theme={null}
const verification = await email.fetchLatest({
  inbox: env.INBOX_PREFIX,
  afterDate: new Date(Date.now() - 60_000),
  timeout: 30_000,
});
return verification.text;
```

Ephemeral inboxes are **not** subject to the self-serve plan's permanent-inbox
cap.

## `email.send`

Send an email from a Momentic-provisioned address.

```ts theme={null}
await email.send({
  subject: "Hello",
  body: "Hello world!",
  to: "momentic+test@gomomentic.com",
  from: "momentic", // Momentic-provisioned inbox name
});
```

## `email.fetchLatest`

Returns the most recent email, polling until one arrives or the timeout elapses.
Throws on timeout.

```ts theme={null}
const msg = await email.fetchLatest({
  inbox: "jeff+test", // Momentic-provisioned inbox name
  afterDate: new Date(), // only fetch emails received after this date
  timeout: 20_000, // milliseconds, keep below the JS step timeout (default 90s)
  // trimWhitespace?: boolean  - default true
});

// msg.subject, msg.from, msg.fromEmail, msg.to, msg.time, msg.secondsAgo
// msg.size, msg.text, msg.html
return msg.text;
```

## `email.fetchAll`

Returns up to `limit` emails without polling. Throws if the inbox is empty.
Defaults: 15 minute window, 3 emails. Max: 24 hours, 10 emails.

```ts theme={null}
const msgs = await email.fetchAll({
  inbox: "jeff+test",
  afterDate: new Date(Date.now() - 60 * 1000), // last 60 seconds
  limit: 5, // default 3, max 10
  // trimWhitespace?: boolean  - default true
});

return msgs.filter((msg) => msg.text.includes("verification code"));
```

## Isolated inboxes

Append a suffix to your provisioned username to create unlimited isolated
inboxes. If your username is `momentic`, `momentic+test@usemomentic.com` is a
separate inbox fetched via `inbox: "momentic+test"`.

Use randomized suffixes (e.g. `Date.now()`) in parallel runs to avoid race
conditions.

<Warning>
  The JavaScript step defaults to a **90 second** timeout. On Momentic cloud,
  this is effectively capped at **60 seconds** by the platform; on the CLI, it
  can be configured up to **10 minutes**. If your `email.fetchLatest` `timeout`
  exceeds the JavaScript step's timeout, set the JavaScript step's **Timeout**
  field high enough to cover the whole script or the step will be killed before
  your code returns.
</Warning>
