Email deliverability
What keeps campaign emails out of the spam folder, and how Swarmhit handles bounces and complaints.
Email outreach lives or dies by the reputation of the sending address. Swarmhit paces sends, threads follow-ups and stops on bounces and complaints, but the domain and mailbox setup is yours. This page is the short checklist.
Before the first campaign
- Authenticate the sending domain. Publish SPF, DKIM and DMARC records for the domain of every connected mailbox. Google Workspace and Microsoft 365 document the exact records; without DKIM most providers file cold email as spam regardless of content. Swarmhit reads these records when a mailbox connects and once a day after that: the mailbox page shows each one with the fix when something is missing, and the mailbox list flags the domain. After changing DNS, use Check again on the mailbox page (or
POST /email-accounts/{id}/check-dns). DKIM keys live under a name the sender picks, so outside Google Workspace and Microsoft 365 a key we cannot find is reported as unknown, not missing. Addresses on consumer domains such as gmail.com need nothing: the provider publishes the records. - Use a mailbox with history. A brand-new address has no reputation. Send real conversations from it for a couple of weeks before it joins a campaign pool, and keep its daily limit low at first.
- Keep the daily limit modest. Each mailbox has its own cap (mailbox settings,
limitsonGET /email-accounts). Emails are paced a few minutes apart per mailbox inside the campaign schedule, so a campaign never sends in bursts. - Write like a person. Campaign emails go out as plain text with light formatting. Short, specific, one question.
Threads and follow-ups
A follow-up email step with config.sameThread: true is sent as a reply under the campaign's first email to that lead (In-Reply-To and References headers), so the recipient sees one conversation. Replies land in the same thread in the inbox, and a reply on any channel ends the sequence.
Testing a mailbox
Run test on the mailbox page sends one ordinary email from the mailbox to our test inbox, the way a campaign email from it goes out. Within a couple of minutes the page shows whether it landed in the inbox or in spam (or did not arrive within 10 minutes), whether SPF, DKIM and DMARC passed as the receiving server saw them, and whether the sending server or the domain is on a Spamhaus blocklist, with the fix for anything that failed. Over the API, start it with POST /email-accounts/{id}/deliverability-test and read deliverabilityTest on the mailbox. One test runs at a time per mailbox, and a mailbox can run 10 a day.
It is one inbox at one provider, so treat a single spam result as a signal to check, not a verdict: fix what failed, then run it again.
Tracking opens and clicks
Each mailbox has two settings. Track opens adds one tiny image to its emails; it is on for mailboxes connected from now on. Track link clicks sends every link through a tracking address first, which some spam filters hold against the sender, so it starts off. A campaign can decide for itself instead (Config tab, or tracking on the campaign in the API: mailbox, the default, follows each mailbox; on or off applies to all its emails). A campaign with an if_email_opened or if_email_clicked step tracks its own emails either way.
- Opens are approximate. Apple Mail and some corporate filters load images on their own, so an open can be counted that nobody made; Outlook and other apps block images, so a real open can be missed. Treat them as a hint, and use them for a follow-up, not for anything stronger.
- Clicks are closer to the truth, but mail security scanners follow every link as the email lands. Opens and clicks in the first two minutes after a send are ignored for that reason.
- Rates are per email, against the emails sent with that tracking on, so a mailbox that tracked nothing shows no rate rather than 0%.
Your own tracking domain
Tracked emails carry our shared tracking address by default, for the open image, tracked links and the unsubscribe link. Any workspace with email can use its own instead, under Settings, Email: enter a subdomain such as track.yourdomain.com, add the one CNAME record shown, and it goes live by itself once the record resolves (minutes to an hour). A domain of your own keeps your links' reputation yours, and recipients only ever see your domain. An organization's tracking domain also covers its workspaces that have none. Emails keep the address they went out with, so removing or changing the domain breaks tracked links and unsubscribe links in emails already sent. The workspace in GET / reports it as trackingDomain.
Bounces and complaints
- Any bounce fails the lead on the step that sent the email (a delivery the server merely delays is not a bounce) and fires the
email.bouncedwebhook. - A hard bounce (the address does not exist) also marks the address on the lead (
emailStatus: bounced,deadAddress: truein the webhook), so from then on the lead stops at any email step it reaches (route it withif_has_emailto avoid that). A soft bounce (mailbox full, greylisting) leaves the address usable. - A spam complaint marks the address as
complained, opts the lead out of email, and firesemail.bouncedwithkind: complaint.
Watch the mailbox counters and stats (GET /email-accounts/{id}/stats): a bounce rate above a few percent means the list is stale, a complaint means the copy or the targeting is off. Pause the mailbox while you fix either.
Opting out
Each campaign has an unsubscribe line (Config tab, or unsubscribe on the campaign in the API): one sentence where the words in [brackets] become the link, for example Not interested? [Let me know]. Write it in the language of your emails. The link opens a short page that asks once and then unsubscribes the person.
-
Add to every email puts the line after the signature of every email the campaign sends.
-
{{unsubscribeLink}}in an email step's message puts the line exactly there instead (it works in the fallback message too, and never makes a fallback required). If a lead gets a fallback that leaves it out, the line still goes after the signature. -
An email that carries the line also gets a one-click
List-Unsubscribeheader, so Gmail and other mail apps can show their own Unsubscribe button next to the sender. With the switch off and no{{unsubscribeLink}}, emails go out exactly as before. -
Unsubscribing opts the address out for the whole workspace (
emailOptOut: trueon every lead with it), so no email step sends to it again, and stops the lead in the campaign that emailed it. LinkedIn steps in other campaigns are not affected. -
Opening the link does nothing on its own: mail security scanners open every link as an email lands, so only the page's button or the mail app's one-click unsubscribe counts. A click on the link is not an open or a click in the stats.
-
Each unsubscribe shows in the lead's activity and fires the
email.unsubscribedwebhook.
A reply asking to stop ends the sequence like any reply, and a spam complaint opts the lead out automatically, link or not.