Your brand's email
Who the email Synq sends your users is from, where their replies go, and sending it from your own domain.
Synq emails your users while they sign in: sign-in codes and links, an address to verify, a password reset and the notices that follow a change. Each comes from your brand. This guide covers who it is from, where replies go, and sending it from a domain of your own.
Who it is from
Out of the box, a brand's email comes from Synq's own sending domain, in the brand's name:
From: "Acme via Synq" <notifications@mail.synq.build>On a plan with your own sending domain (branding.custom_email_domain, Pro and up), it can come from a domain you verified instead:
From: "Acme" <no-reply@mail.acme.com>signed with your domain's own DKIM key, its bounces handled at a Return-Path under it, so it passes SPF, DKIM and DMARC as your domain. The name and the part before the @ are yours to choose. The email's words stay Synq's, whatever domain it comes from.
Read how a brand's email goes out answers effective: exactly what the next email carries, its from, its reply_to, whether it is custom (your domain) or fallback (via Synq) and, for the fallback, why:
fallback_reason | Why the email comes via Synq |
|---|---|
no_domain | The brand picked no domain |
plan | The org's plan doesn't send from its own domain (it moved down, say) |
domain_pending | The brand's domain isn't verified yet |
domain_failing | The domain stopped verifying: a record it needs went missing |
Whichever the reason, email keeps arriving: it falls back from the next email on, and goes back to your domain the moment it can.
Where replies go
On every plan, a brand can set a reply-to address, where replies to its email go: your support inbox, say. Without one, the email has no Reply-To at all, and its footer says replies aren't read (and names the brand's support address if it has one). Replies never reach Synq.
Set it with reply_to. A new address is used only once someone who reads it confirms it: Synq emails it a link to a page whose button confirms it, so a mail scanner opening the link confirms nothing. The link works once, for a day; send it again at most 5 times a day per brand. Until it is confirmed, reply_to.status is pending_confirmation and replies go nowhere. An address needs no email when it is:
- the address of the person setting it, verified at Synq, or
- on a sending domain the org verified.
Changing the address takes the confirmation away. An address Synq can't email is refused with email_undeliverable, and nothing is kept. The address is a plain one in ASCII, since every email carries it in a header: no quoted part before the @, a dot only between words, and an internationalized domain in punycode (xn--…).
Sending from your own domain
1. Add the domain
Use a subdomain kept for this, such as mail.acme.com: it keeps your users' email apart from your own mailboxes, their reputation and their DMARC policy. Add a sending domain with domain. $SYNQ_API here is the management API, https://api.synq.build:
curl -X POST "$SYNQ_API/v1/orgs/$ORG/email-domains" \
-H "Authorization: Bearer $SYNQ_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"domain": "mail.acme.com"}'It answers the domain with its records. A name is held by one Synq account at a time (email_domain_unavailable otherwise); mailbox providers' domains, names reserved for testing and Synq's own are refused with email_domain_invalid and its reason. An org has at most 10 sending domains (email_domain_limit_reached) and adds at most 10 a day. Without the plan, adding one is plan_feature_unavailable.
If Synq can't reach its email provider just then, the domain is pending_setup, with no records yet and problem: setup_pending: there is nothing to do, and its records appear once Synq has registered it.
2. Publish the records
| Record | Type | Name | Value |
|---|---|---|---|
| DKIM key | TXT | <selector>pm._domainkey.mail.acme.com | k=rsa; p=…, as the API gives |
| Return-Path | CNAME | pm-bounces.mail.acme.com | pm.mtasv.net |
| DMARC, advised | TXT | _dmarc.mail.acme.com | v=DMARC1; p=none; |
Both the DKIM key and the Return-Path are required. DMARC isn't, but mailbox providers trust a domain that has a policy: start with p=none, then tighten it once its reports look right. A policy on your organizational domain (_dmarc.acme.com) counts too.
Notes for common DNS providers:
- Cloudflare: set the CNAME to DNS only (grey cloud). A proxied CNAME answers with addresses, and never verifies.
- GoDaddy and Namecheap: type only the part before your domain as the name (
pm-bounces.mail); they add the domain themselves. Typing it in full makespm-bounces.mail.acme.com.acme.com. - Amazon Route 53: type the full name, and put the TXT value in quotes. A long value may be split into quoted parts, which Synq joins.
3. Verify it
Synq checks a domain waiting for its records at 1, 5 and 15 minutes and an hour after adding it, every 6 hours for 3 days, then daily. Check it now rather than wait (once a minute). Once both required records resolve from public DNS and Synq's email provider agrees, the domain is verified, the org's owners and admins are emailed, and the audit log records email_domain.verified. DNS changes can take minutes, sometimes up to 48 hours, to show everywhere.
While a record is wrong, the domain's problem says why, and each record's status says what Synq saw at it (found, missing, or mismatch with what was seen):
problem | What to do |
|---|---|
record_missing | Add the record, or wait for it to show |
record_mismatch | Replace the value with the one the API gives |
zone_appended_twice | Your DNS provider added your domain to the name again: type only the part before it |
cname_proxied | Set the Return-Path CNAME to DNS only |
return_path_conflict | Remove the other record at the Return-Path name |
postmark_refused | Nothing yet: the provider refused it as an email went out, which went via Synq; Synq checks it again |
A domain that never verifies is deleted after 30 days, with a warning to its owners 3 days before.
4. Send from it
Point the brand at it with sender:
{
"sender": {
"email_domain_id": "edm_01h455vb4pex5vsknk084sn02q",
"local_part": "no-reply",
"name": "Acme"
}
}local_part is the part before the @ (no-reply unless set; never postmaster, abuse, hostmaster or mailer-daemon). name is who the email says it is from, the brand's name unless set: never an address, <, > or ", nor a character that reorders the text around it (such as U+202E). A domain that isn't verified yet can be picked: email comes from it once it is. "email_domain_id": null goes back to Synq's domain, on any plan. Then send yourself a test: exactly what your users' next email carries, to your own verified address.
When a domain stops verifying
Synq checks every verified domain daily. One check that misses a record is looked at again in 15 minutes; a second in a row makes the domain failing: its brands' email comes via Synq from the next email on, the owners and admins are emailed, and the audit log records email_domain.failed. Synq checks a failing domain every 15 minutes for 2 hours, then hourly, and it verifies again on the first check that passes. A domain still failing a week on gets a reminder. If the email provider refuses the domain while an email is going out, that email goes via Synq at once, so the person waiting for a code still gets it, and the domain is checked again.
When the email provider moves to a new DKIM key, the domain's records gain a dkim_pending key: publish it beside the current one, and keep the current one until the records no longer list it.
Downgrading and deleting
On a plan without your own domain, email comes via Synq from the next email on; the domains and the brand's settings stay, and moving back up sends from the domain again at once. Listing, reading and deleting domains never need the plan. Deleting a domain frees its name at once, and is refused with email_domain_in_use, naming the brands, while a brand sends from it.