Documentation menu

Contacts & sending from MailInApp

Besides exporting HTML for your ESP, you can send finished emails directly from the dashboard — to a single contact, a selection, or a whole list. Delivery still runs through your own SMTP relay, so your sending domain and reputation stay yours.

Contact lists

The Contacts tab holds your lists. Every list has an email column (that's what makes it sendable) plus any columns you like — name, plan, city — and each column doubles as a {{field}} merge tag in the studio.

A contact list is a data source like any other: connect it in the studio's Data panel with the Audience role and it's both who the email sends to and where bare {{field}} merge tags get their per-recipient values — the canvas previews with real contact data. See Data sources & merge tags.

Import a CSV

Already have your contacts somewhere else? Import CSV (on the Contacts tab, or inside a list to append to it) accepts the files ESPs and spreadsheets export: comma-, semicolon- or tab-separated, with a header row. Quoted values, Excel BOMs and "" escapes are handled.

The header names become your columns. If no column is named email, the import looks for the column that actually contains addresses (e.g. "E-Mail Address") and uses it as the email column. Nothing is stored until you hit save, so you can review — and fix — the table first.

Export a CSV

Download CSV on a list (and on the suppression panel) gives you a snapshot backup any time — useful before a big filtered send, or just to keep an off-platform copy. It round-trips through the same importer above.

Configure sending once

Direct sends need a sending method configured under Settings, in one of two ways:

  • No ESP yet? Verify your own domain and MailInApp sends on your behalf — no SMTP credentials to generate or rotate. This is the recommended default if you don't already have an SMTP-capable provider.
  • Already have an ESP? Point MailInApp at its SMTP relay — SendGrid, Brevo, Mailgun, Amazon SES, even a Gmail app password for small tests. Any provider with an SMTP endpoint works. Use Test & save to verify the connection before your first send. Your SMTP password is a credential: it is stored server-side only and comes back masked everywhere.

Both methods feed the same send pipeline — manual sends, scheduled sends, and everything else on this page behave identically either way.

Send a test first

Before sending to your list, use Send test to mail yourself (or anyone) a fully rendered copy — prefilled with your account email, prefixed [Test] in the subject, and carrying a real working live-view link, so interactive blocks are actually testable. A test send doesn't touch your data source, doesn't count against the 200-recipient cap, and doesn't appear in send history.

Send

From an email's card on the dashboard, hit Send:

  1. The recipients come from the email's audience — the contact list connected with the Audience role in the studio's Data panel. No list linked yet? Pick one right there.
  2. Choose everyone, or tick individual contacts — sending to one contact is just a one-row selection. Rows you've already sent to are labeled with the date of their last send, so you don't lose track of who's been reached (this is informational only — it doesn't change your selection for you).
  3. Set the subject (merge tags work there too, and ✨ Suggest drafts a few options with AI — see AI-assisted copy) and send.

Every recipient gets their own compiled email: merge tags resolved from their row, and a personal signed live view link. Interactive blocks render in their static fallback tier with link-first interactions — poll options and ratings are links that confirm before recording, forms and carousels open the hosted live view — so the email works in every client, and nothing is ever recorded from a bare link prefetch.

Subject-line A/B testing

Add up to 4 more subject-line variants under the main subject field to split-test wording — 2 to 5 total. Each recipient is deterministically assigned one variant based on their email address, so retries and resends never reshuffle who saw which subject. Results — open rate and response rate per variant — show up on the project's Responses page once the send goes out; see Subject-line A/B testing. Recurring sends stay single-subject for now — there's no variant picker on the schedule form.

Segment your audience

Above the recipient list, Audience filter builds a rule (e.g. ticket_status = Resolved and resolved_date within the last 7 days) against your data source's fields, then Apply filter to selection sets your selection to whatever currently matches — a rolling segment instead of a one-off manual pick. Combine rules with AND/OR the same way you already do for a block's visibility conditions in the studio.

Soft-launch a send

Soft launch samples a random slice of your current selection — set a percentage and hit Sample to send to that fraction first. Once you're happy with the results, Select remaining (not yet sent) picks up everyone in the list who hasn't received this email yet, so the follow-up wave never double-sends to the sample.

Recurring sends

For an audience that changes over time — "resolved 3–7 days ago" matches different rows every day — a Recurring send re-evaluates your audience filter against the linked data source's current rows on a schedule (daily or weekly, at a UTC hour you choose) and sends only to matches that haven't already received this email, picking up where the last run left off. Each run writes a normal send-history record, same as a manual send, and a schedule whose relay fails on every recipient for three consecutive runs disables itself automatically rather than silently burning through your list.

Push contacts from your helpdesk or CRM

Instead of re-exporting a CSV before every send, a contacts list can accept pushes directly: mint an API key for the list under its settings in the Contacts tab, then have your own system (a helpdesk automation, a CRM workflow) call:

POST /api/datasources/<datasourceId>/rows
Authorization: Bearer <apiKey>
Content-Type: application/json

{ "rows": [{ "email": "[email protected]", "ticket_status": "Resolved" }] }

Rows are upserted on lowercase email — a known address updates in place, a new one appends — and existing rows are never reordered or deleted, since response attribution is positional (row:<n>) and reordering would break historical joins. Batches are capped at 500 rows and rate-limited per key. The key is shown once when minted (or regenerated) and masked everywhere after, like every other credential in MailInApp; Revoke disables the integration without touching existing rows.

Send history

Every real send (not test sends) is recorded and shown above the recipient picker — date, subject, and how many were sent, failed, or skipped. Nothing is ever deleted client-side on refresh; history is the source of truth for what's actually gone out.

Unsubscribe & suppression

The Footer preset includes an {{unsubscribe_url}} merge tag that resolves to a one-click unsubscribe page for that specific recipient. Unsubscribing is account-wide: it suppresses the address from every project you send from, not just the one they clicked from — so a recipient never has to opt out of each campaign separately.

Addresses your SMTP relay rejects synchronously at send time (invalid mailbox, relay refusal) are suppressed the same way, so a dead address isn't retried on every future send. (A relay accepting a message and bouncing it later, asynchronously, isn't observable without an ESP-specific webhook — that's out of scope today.)

Suppressed addresses show a bounced or unsubscribed badge on the Contacts tab. Both are resubscribable — a full mailbox or a stray click isn't necessarily permanent — and suppressed rows are automatically skipped (and reported separately from failures) on future sends.

After the send

Exactly like an ESP send: interactions flow into responses, grouped per contact, and your webhook fires per event if you configured one.

Limits

  • Up to 200 recipients per send (one list, one run of a recurring schedule). For bigger audiences, use the export & ESP workflow; a recurring send also just catches up whoever's left on its next run.
  • Rows without a valid email address are skipped and reported after the send.
  • Importing a CSV drops rows whose email address already appeared earlier in that same file, so re-importing an overlapping export doesn't create duplicate sends — you'll see a "Skipped N duplicate email(s)" notice.
  • The contacts push API caps each batch at 500 rows.