HubSpot transactional email: route it through your own domain with MailKite — MailKite<br>Beta<br>50% off your first year — founding rate for the first 1,000 customers.<br>View pricing →
Sign in · Start free
All posts<br>HubSpot sends your transactional email from HubSpot’s infrastructure. Password resets, form confirmations, workflow-triggered emails — they go out through HubSpot’s SMTP, with HubSpot’s DKIM signature, from HubSpot’s IP. Your brand name is there, but your domain’s reputation isn’t doing the work.
For marketing emails, this is fine — HubSpot’s deliverability team handles it. For transactional email, it’s a problem. Your customers expect password resets and form confirmations to come from you, not from a platform they’ve never heard of. And when Gmail sees a From: you@yourcompany.com email signed by HubSpot’s key, DMARC alignment fails.
MailKite fixes this. Here’s how to route HubSpot’s transactional email through your own DKIM-signed domain.
The problem with HubSpot’s default
HubSpot’s transactional email product sends through its own SMTP servers. When you configure a sending domain in HubSpot, it sets up DKIM under HubSpot’s key — not yours. This means:
DKIM alignment fails. The signature is hubspot.com, not yourcompany.com. DMARC requires the signing domain to match the From domain (or be a subdomain of it).
SPF may fail. HubSpot’s sending IP isn’t in your SPF record. If you haven’t added HubSpot to your SPF, the email gets a hard fail.
No visibility. HubSpot shows open/click rates for marketing email but has limited delivery diagnostics for transactional sends.
The fix: use MailKite as the SMTP relay for HubSpot’s transactional email, so every message is signed with your DKIM key.
The setup
1. Verify your domain in MailKite
Add your domain to the MailKite dashboard. Publish the DNS records (MX, SPF, DKIM, DMARC). This takes under 5 minutes.
2. Configure HubSpot’s SMTP
In HubSpot, go to Settings → Transactional Email → Sending Domain and add your verified domain. Then configure the SMTP relay:
SettingValueSMTP Serversmtp.mailkite.devPort587UsernamemailkitePasswordYour API key (mk_live_…)TLSRequired (STARTTLS)<br>HubSpot’s transactional email API can also send directly — but SMTP gives you the same MailKite pipeline (DKIM signing, logging, retries) as every other integration.
3. Verify DKIM alignment
Send a test transactional email (trigger a form submission, password reset, or workflow). Check the headers in Gmail:
Authentication-Results: mx.google.com;<br>dkim=pass header.d=yourcompany.com<br>spf=pass<br>dmarc=pass<br>All three should pass. If DKIM shows header.d=hubspot.com instead of your domain, the relay isn’t configured correctly.
When to use SMTP vs HubSpot’s API
HubSpot’s transactional email has two paths: SMTP and the API. Here’s when to use each:
Use SMTP when…Use HubSpot’s API when…You want zero config — point and sendYou need HubSpot’s email tracking (opens, clicks)You’re sending from a non-HubSpot app (Laravel, WordPress, etc.)You want email to appear in HubSpot’s timeline automaticallyYou want MailKite’s deliverability controls and logsYou’re building marketing sequences inside HubSpotYou need inbound email routing (replies → CRM)You’re using HubSpot’s template editor exclusively<br>The key insight: SMTP is org-wide. Once configured, every HubSpot email — workflows, sequences, transactional — routes through MailKite. The API path is per-email and requires code.
Receiving inbound email → HubSpot CRM
When a customer replies to your email, MailKite can POST the reply to a webhook. This example creates a note on the matching HubSpot contact:
// hubspot-webhook.js — Cloudflare Worker or any serverless platform<br>export default {<br>async fetch(request, env) {<br>if (request.method !== "POST") return new Response("OK");
const payload = await request.json();<br>const { from, subject, text } = payload;
// Look up the contact by email<br>const searchRes = await fetch(<br>"https://api.hubapi.com/crm/v3/objects/contacts/search",<br>method: "POST",<br>headers: {<br>Authorization: "Bearer " + env.HUBSPOT_API_KEY,<br>"Content-Type": "application/json",<br>},<br>body: JSON.stringify({<br>filterGroups: [{<br>filters: [{<br>propertyName: "email",<br>operator: "EQ",<br>value: from,<br>}],<br>}],<br>properties: ["email", "firstname", "lastname"],<br>}),<br>);
const { results } = await searchRes.json();<br>if (!results.length) return new Response('{"ok":true}', { status: 200 });
const contactId = results[0].id;
// Create a note on the contact<br>await fetch(<br>"https://api.hubapi.com/crm/v3/objects/contacts/" + contactId + "/associations/notes",<br>method: "POST",<br>headers: {<br>Authorization: "Bearer " + env.HUBSPOT_API_KEY,<br>"Content-Type": "application/json",<br>},<br>body: JSON.stringify({<br>properties: {<br>hs_note_body: "Inbound emailSubject: " + subject + "" + text,<br>hs_timestamp: Date.now().toString(),<br>},<br>}),<br>);
return new Response('{"ok":true}', { status: 200 });<br>},<br>};<br>Set your domain’s webhook to this endpoint. Every inbound email becomes a CRM activity — visible on the...