Interactions & analytics
When a recipient votes in a poll, submits a form or taps a rating, that interaction is recorded by MailInApp's hosted endpoints and attributed to your project — in real time.
How interactions travel
Interactive blocks reach the recording endpoints in two ways, matching the fallback philosophy:
- Links (universal). Every option in a poll or rating is a plain link. Tapping it opens a lightweight hosted page that confirms the action and records it. This path works in 100% of email clients.
- In-email form posts (enhancement). In clients that support it (Gmail web/Android, Yahoo), forms and polls can submit directly from the email using standard HTML form encoding — no page hop. After submission, recipients are redirected to the page you choose.
Both paths accept the same data, so results end up in one place regardless of which client the recipient used.
A product block's Buy now click is the one exception: it can't record through this endpoint at all, because a purchase can only complete on Stripe's own hosted checkout page. It still lands as a purchase event here — with amount, currency and quantity — but only once Stripe's webhook confirms the payment actually cleared, never on the buyer's click alone.
Protected against bots and scanners
Corporate security tools prefetch every link in every email they scan. If a bare link click were enough to record a vote, your poll results would be full of robots. MailInApp records nothing on a simple GET: link-based actions require the recipient's explicit confirming action, and live-view interactions are recorded via form posts. See Live view links.
Because the endpoints are public by necessity (an inbox can't authenticate), every payload is validated server-side, and personalized submissions are attributed through the same signed tokens that protect live view links — a forged or mismatched token is rejected.
Two more layers keep results honest:
- Per-recipient dedup. A recipient's own vote, rating, reveal or form submission counts once — re-clicking their own link (an eager double-tap, a retried page load) is a no-op, not a second row. Repeat carousel-slide views are deliberately not deduped, since repeats are a meaningful engagement signal there rather than double-counting.
- Anonymous flood throttling. A campaign's
campaignIdis plainly visible in the email's own HTML source, so nothing stops a script from posting arbitrary votes with no recipient token at all. Unattributed submissions are capped per IP address, per campaign, per minute. This is a best-effort net, not precise identity — shared corporate or webmail networks can put many real recipients behind one IP — so the cap stays generous enough not to block a legitimate burst of opens.
What gets recorded
Each interaction event captures:
- the project (campaign) it belongs to,
- the block that produced it (which poll, which form),
- the value (the chosen option, the submitted fields, the star count),
- the recipient row, when the email was personalized with a data source — so you can see who answered, not just how many,
- a timestamp.
Survey lifecycle
A project can be given a close date and/or a response cap (set alongside its send settings). Once either is reached, the recording endpoints stop accepting new events for that project — the live view swaps interactive blocks for a closed notice instead of erroring — while everything collected before closing stays exactly as recorded. See Responses & webhooks.
Click tracking
Plain links — a button, a linked image, a social icon — aren't a poll or a rating, but they're still worth knowing about. When an email was sent with a personalized recipient link, MailInApp routes these plain clicks through a tracked redirect on the way to their real destination: the click is recorded, then the recipient lands on the URL you set, with no extra step and no delay. Emails with no recipient context (for example a freeform send through the transactional API) link straight to the destination instead — there's nothing to attribute a click to.
Unlike votes and ratings, clicks are never deduped — a recipient clicking the same button five times counts as five clicks, since repeat clicks are a meaningful engagement signal here, not double-counting. Results roll up into a per-block click heatmap — see Responses & webhooks.
Scroll depth
The hosted live view page also reports how far a recipient scrolled — 25%, 50%, 75%, 100% of the page — as they read. This is the one place in MailInApp that runs a small script: the mailed email itself stays 100% script-free, as it must, but the live view is already a normal hosted web page, so a scroll listener there doesn't compromise anything. Milestones roll up into a scroll-depth funnel — see Responses & webhooks.
Open tracking
Every email sent from the dashboard also carries a small, invisible open-tracking pixel, so you have a signal for "opened but didn't engage" versus "never opened" alongside explicit interactions. It's shown in the Responses view as a distinct Opened indicator (first-open timestamp) per recipient rather than mixed into the interaction list.
This is a best-effort minimum, not a precise measurement: Apple Mail Privacy Protection and Gmail's image proxy both prefetch or cache images independent of whether the recipient actually opened the message, so opens can be undercounted or false-positive. Treat it as a directional signal, not a source of truth.
Where results live
Interaction data is collected per project and flows back to you three ways:
- Per-recipient responses — the dashboard's Responses view groups every interaction by recipient, joined with your data source so you see who answered, not just how many. See Responses & webhooks.
- Webhooks — each interaction can be pushed to your own endpoint the moment it arrives, signed so you can verify it came from MailInApp. Also covered in Responses & webhooks.
- Live results for recipients — poll blocks can surface live results to recipients on their hosted results page.
Privacy note: MailInApp records the interactions recipients deliberately make — votes, submissions, ratings — plus the open-tracking pixel described above. The endpoints are designed not to log any other incidental tracking on bare link fetches.