# Invitations, reminders & expiry

Let formbase email the request link, chase people who go quiet, and close requests that go stale.

> ✅ **Pro feature** — included in the Pro plan.


## Invitations, reminders & expiry

Delivering the link, chasing the people who go quiet, and deciding when a request stops being worth waiting for.

> ℹ️ **Two ways to deliver a link**
> <p>
>     Every request comes back with a <code>url</code>. You can send it yourself — in your own email, a Slack message, an SMS — or ask
>     formbase to email it. Sending it yourself works on every plan. Letting formbase send invitations and reminders requires a{' '}
>     <strong>Pro or Business plan</strong>; a Free account can have formbase email its first 10 invitations to try it (see{' '}
>     <a href="/subscription-billing/limits-quotas#free-invitations">free invitations</a>).
>   </p>

<h2 id="invitation">The request invitation</h2>

<p>
  Create a request with <code>delivery: "email"</code> and a recipient email address, and formbase sends the{' '}
  <strong>request invitation</strong>: a short email carrying a button that opens the request link.
</p>

<p>
  You author it once per form, not once per request. In the editor, open <strong>Settings → E-mail Notifications</strong> and scroll to the{' '}
  <strong>Requests</strong> group at the bottom:
</p>

<p>
  There is no free-text message from the caller — an automation cannot inject a paragraph into this email. What it <em>can</em> do is supply
  values: mention a context field or a prefilled field in the subject or body and each recipient gets their own version. That keeps the copy
  under your control while still reading as if it were written for them.
</p>

> 💡 **Translate it**
> <p>
>     If the form has published languages, the invitation follows the request's <code>language</code>. Translate the email copy alongside the
>     rest of the form — see <a href="/building-forms/translating-form-content">Translating form content</a>.
>   </p>

<h3 id="delivery-status">Delivery status</h3>

<ul>
  <li>
    The invitation is sent at most once. It is queued, and dropped unsent if the request ends before the queue reaches it — nobody is
    invited to a dead link.
  </li>
  <li>
    If it never arrived, send a reminder. <code>requests.remind</code> carries the same link and counts against the eight-reminder cap. On
    Free, where reminders aren't available, copy the request's link and send it yourself.
  </li>
  <li>Invitations and reminders share a budget of 10 emails per day per form and recipient address.</li>
</ul>

<h2 id="reminders">Reminders</h2>

<p>
  A <strong>reminder schedule</strong> is an ordered list of idle offsets — 1 day, 3 days, 1 week — after which formbase emails someone who
  has gone quiet. One schedule serves two kinds of target: a public-link respondent sitting on an unfinished draft, and a request recipient
  who has not completed.
</p>

<p>
  It lives in <strong>Settings → E-mail Notifications → Send reminders</strong>. That switch is the master: turn it off and neither channel
  gets the form's schedule.
</p>

<h3 id="how-the-schedule-runs">How the schedule runs</h3>

<ul>
  <li>
    Offsets are measured from the target's <strong>last activity</strong>, not from creation. A schedule of 1 day then 3 days means "one day
    idle, then three days idle".
  </li>
  <li>
    <strong>New activity restarts it.</strong> If the recipient opens the request and answers something, the clock goes back to the first
    step.
  </li>
  <li>
    <strong>It stops on its own</strong> once the request is completed, expired, or canceled.
  </li>
  <li>
    <strong>A sweep runs every 15 minutes</strong>, so a reminder lands within a quarter of an hour of the step falling due, not to the
    second. A schedule that fell far behind is not fired as a burst: the gap you put between two steps is honoured.
  </li>
  <li>
    <strong>Eight reminders is the hard ceiling</strong> for one request, scheduled and manual together. Activity can restart a schedule
    forever; this is what stops that becoming a loop.
  </li>
</ul>

<h3 id="per-request">Overriding per request</h3>

<p>
  An automation can pass its own <code>reminders</code> when creating a request — <code>["2d","5d"]</code> for a schedule of its own, or an
  empty list to switch reminders off for that one request. An explicit schedule wins even over the form's master switch, because a caller
  that passed one asked for reminders on this request specifically.
</p>

<p>
  Leave <code>reminders</code> out and the request inherits the form's schedule, if the master switch is on and the request has a recipient
  address.
</p>

<h3 id="manual">Chasing someone now</h3>

<p>
  You do not have to wait for the next step. <strong>Send reminder</strong> in the request drawer — or <code>requests.remind</code> from an
  automation — queues one immediately. The automatic schedule is untouched: the next scheduled reminder still lands when it was going to.
</p>

<p>Two floors apply: at least ten minutes between manual reminders, and the same overall ceiling of eight per request.</p>

<h2 id="expiry">Expiry</h2>

<p>
  Every request has a hard end. When it passes, the link stops working, the status becomes <strong>expired</strong>, and your automation is
  told through the callback — so a workflow that has been parked for a month resumes instead of hanging forever.
</p>

<ul>
  <li>
    Default: <strong>30 days</strong> after creation.
  </li>
  <li>
    Maximum: <strong>365 days</strong>. Pass <code>expiresAt</code> as a millisecond timestamp to set your own.
  </li>
  <li>After expiry the link shows the outcome page — a plain notice, never the form.</li>
  <li>
    A sweep flips lapsed requests every 15 minutes, so the status and the callback follow <code>expiresAt</code> within a quarter of an
    hour. The link itself stops opening the moment the expiry passes.
  </li>
</ul>

```
{
  "method": "requests.create",
  "params": {
    "formId": "j57...",
    "recipient": { "email": "ada@acme.com", "name": "Ada" },
    "delivery": "email",
    "reminders": ["1d", "3d"],
    "expiresAt": 1795392000000,
    "callbackUrl": "https://automation.example/webhook/resume-abc"
  }
}
```

<div class="not-prose grid gap-3 sm:grid-cols-2">
  - [The Requests page](/requests/managing-requests) — Remind and cancel by hand.
  - [Troubleshooting](/requests/troubleshooting) — When an invitation fails or bounces.
  - [Custom email domains](/branding-domains/custom-email-domains) — Send from your own domain.
</div>
