Email Integration

Configure domains for email sending with proper authentication.

Overview

Integrate your domains with Transactional Email for proper email authentication. Set up SPF, DKIM, and DMARC automatically or manually.

Quick Setup

The fastest way to configure a domain for email:

TypeScript:

// Apply email preset - sets up all required records
await client.domains.dns.applyPreset('example.com', {
  preset: 'TRANSACTIONAL_EMAIL',
});
 
// Verify configuration
const verification = await client.domains.verifyEmail('example.com');
console.log('Email configuration valid:', verification.isValid);

Python:

# Apply email preset
client.domains.dns.apply_preset(
    "example.com",
    preset="TRANSACTIONAL_EMAIL"
)
 
# Verify configuration
verification = client.domains.verify_email("example.com")
print(f"Email configuration valid: {verification.is_valid}")

Email Authentication Records

SPF Record

SPF (Sender Policy Framework) specifies which servers can send email for your domain.

await client.domains.dns.create('example.com', {
  type: 'TXT',
  name: '@',
  value: 'v=spf1 include:usetransactional.com ~all',
  ttl: 3600,
});

DKIM Records

DKIM (DomainKeys Identified Mail) adds a digital signature to emails.

// Get DKIM records to add
const dkim = await client.email.domains.getDkimRecords('example.com');
 
for (const record of dkim.records) {
  await client.domains.dns.create('example.com', {
    type: 'TXT',
    name: record.name,
    value: record.value,
    ttl: 3600,
  });
}

DMARC Record

DMARC (Domain-based Message Authentication) defines how to handle failed authentication.

await client.domains.dns.create('example.com', {
  type: 'TXT',
  name: '_dmarc',
  value: 'v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100',
  ttl: 3600,
});

MX Records (for receiving)

If you want to receive email at this domain:

await client.domains.dns.create('example.com', {
  type: 'MX',
  name: '@',
  value: 'inbound.usetransactional.com',
  priority: 10,
  ttl: 3600,
});

Verification

Check Email Configuration

const verification = await client.domains.verifyEmail('example.com');
 
console.log('SPF:');
console.log('  Valid:', verification.spf.valid);
console.log('  Record:', verification.spf.record);
if (!verification.spf.valid) {
  console.log('  Error:', verification.spf.error);
}
 
console.log('DKIM:');
console.log('  Valid:', verification.dkim.valid);
for (const key of verification.dkim.keys) {
  console.log(`  ${key.selector}: ${key.valid ? 'Valid' : 'Invalid'}`);
}
 
console.log('DMARC:');
console.log('  Valid:', verification.dmarc.valid);
console.log('  Policy:', verification.dmarc.policy);
 
console.log('MX:');
console.log('  Valid:', verification.mx.valid);
console.log('  Records:', verification.mx.records.length);

Verification Status

const status = await client.email.domains.getVerificationStatus('example.com');
 
switch (status.status) {
  case 'VERIFIED':
    console.log('Domain fully verified');
    break;
  case 'PENDING':
    console.log('Verification pending');
    console.log('Missing:', status.missingRecords);
    break;
  case 'FAILED':
    console.log('Verification failed:', status.errors);
    break;
}

Linking Domain to Email

Add Domain to Email Service

// Register domain with email service
const emailDomain = await client.email.domains.create({
  domain: 'example.com',
  returnPathSubdomain: 'bounce', // bounce.example.com
});
 
console.log('Domain added to email service');
console.log('Return path:', emailDomain.returnPath);
 
// Get required DNS records
const dnsRecords = await client.email.domains.getDnsRecords('example.com');
 
console.log('Add these DNS records:');
for (const record of dnsRecords) {
  console.log(`${record.type} ${record.name}: ${record.value}`);
}

Auto-configure DNS

If the domain is managed by Transactional Domains:

// Auto-configure all email DNS records
await client.email.domains.autoConfigureDns('example.com');
 
console.log('DNS records automatically configured');

Return Path (Bounce Handling)

Set up return path for bounce handling:

// CNAME for return path
await client.domains.dns.create('example.com', {
  type: 'CNAME',
  name: 'bounce',
  value: 'bounce.usetransactional.com',
  ttl: 3600,
});

Custom Tracking Domain

Use your own domain for email link tracking:

// Add tracking subdomain
await client.domains.dns.create('example.com', {
  type: 'CNAME',
  name: 'track',
  value: 'track.usetransactional.com',
  ttl: 3600,
});
 
// Configure in email settings
await client.email.settings.update({
  trackingDomain: 'track.example.com',
});

Subdomain for Sending

Use a subdomain for transactional email:

// Create subdomain records
const subdomain = 'mail.example.com';
 
await client.domains.dns.createBulk('example.com', [
  // SPF for subdomain
  {
    type: 'TXT',
    name: 'mail',
    value: 'v=spf1 include:usetransactional.com ~all',
  },
  // DKIM for subdomain
  {
    type: 'TXT',
    name: 'dkim1._domainkey.mail',
    value: 'k=rsa; p=...',
  },
  // DMARC for subdomain
  {
    type: 'TXT',
    name: '_dmarc.mail',
    value: 'v=DMARC1; p=reject; rua=mailto:dmarc@example.com',
  },
]);
 
// Register subdomain for sending
await client.email.domains.create({
  domain: subdomain,
});

BIMI (Brand Indicators)

Display your logo in email clients:

// Add BIMI record
await client.domains.dns.create('example.com', {
  type: 'TXT',
  name: 'default._bimi',
  value: 'v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem',
  ttl: 3600,
});

BIMI Requirements

  1. DMARC policy must be p=quarantine or p=reject
  2. Logo must be SVG Tiny PS format
  3. VMC certificate (optional but recommended)

MTA-STS

Enforce TLS for incoming mail:

// Add MTA-STS DNS record
await client.domains.dns.create('example.com', {
  type: 'TXT',
  name: '_mta-sts',
  value: 'v=STSv1; id=20240115',
  ttl: 3600,
});
 
// MTA-STS policy needs to be hosted at:
// https://mta-sts.example.com/.well-known/mta-sts.txt

TLS Reporting

Receive reports about TLS failures:

await client.domains.dns.create('example.com', {
  type: 'TXT',
  name: '_smtp._tls',
  value: 'v=TLSRPTv1; rua=mailto:tls-reports@example.com',
  ttl: 3600,
});

Troubleshooting

SPF Issues

const verification = await client.domains.verifyEmail('example.com');
 
if (!verification.spf.valid) {
  console.log('SPF Issue:', verification.spf.error);
 
  // Common fixes:
  // - Multiple SPF records: Merge into one
  // - Too many lookups: Use ip4/ip6 instead of include
  // - Syntax error: Check record format
}

DKIM Issues

if (!verification.dkim.valid) {
  for (const key of verification.dkim.keys) {
    if (!key.valid) {
      console.log(`DKIM ${key.selector}: ${key.error}`);
      // Common fixes:
      // - Record not found: Add TXT record
      // - Key mismatch: Regenerate DKIM keys
      // - Syntax error: Check for line breaks
    }
  }
}

DMARC Issues

if (!verification.dmarc.valid) {
  console.log('DMARC Issue:', verification.dmarc.error);
 
  // Common fixes:
  // - No DMARC record: Add _dmarc TXT record
  // - Invalid policy: Use none, quarantine, or reject
  // - SPF/DKIM required: Must pass at least one
}

Best Practices

1. Start with Monitoring

// Start with p=none to monitor
await client.domains.dns.create('example.com', {
  type: 'TXT',
  name: '_dmarc',
  value: 'v=DMARC1; p=none; rua=mailto:dmarc@example.com; pct=100',
});
 
// After monitoring, move to quarantine
// v=DMARC1; p=quarantine; ...
 
// Finally, enforce with reject
// v=DMARC1; p=reject; ...

2. Use Subdomains for Different Purposes

mail.example.com - Transactional email
marketing.example.com - Marketing email
support.example.com - Support notifications

3. Regular Verification

// Run weekly verification
const domains = await client.domains.list();
 
for (const domain of domains) {
  const verification = await client.domains.verifyEmail(domain.domainName);
  if (!verification.isValid) {
    alertAdmin(`Email config issue on ${domain.domainName}`);
  }
}

Next Steps