Domains
Add and verify your domains to send emails with your own sender identity.
Why Verify Domains?
Domain verification improves email deliverability and protects your brand:
- Better deliverability - Verified domains have higher inbox placement rates
- Brand protection - DKIM signing prevents email spoofing
- Professional appearance - Send from your own domain, not a shared sender
Add a Domain
Register a domain for verification.
POST /v1/domainsconst domain = await client.domains.create({
domain: 'mail.example.com',
});
console.log(domain.status); // 'pending'
console.log(domain.dnsRecords); // DNS records to configureDNS Configuration
After adding a domain, you will receive DNS records to configure. Add these records to your DNS provider:
Required Records
| Type | Host | Value | Purpose |
|---|---|---|---|
| TXT | v=spf1 include:spf.veilmail.xyz ~all | SPF (sender verification) | |
| TXT | veilmail._domainkey | k=rsa; p=MIGfMA0GCS... | DKIM (signing) |
| CNAME | bounce | bounce.veilmail.xyz | Bounce handling |
DNS Propagation
DNS changes can take up to 48 hours to propagate. Most changes are visible within a few minutes to a few hours.
Verify Domain
After configuring DNS records, trigger verification to check the setup.
POST /v1/domains/:id/verifyconst domain = await client.domains.verify('domain_xxxxx');
if (domain.status === 'verified') {
console.log('Domain verified successfully!');
} else {
// Check which records are still pending
for (const record of domain.dnsRecords) {
console.log(`${record.type} ${record.host}: ${record.status}`);
}
}Domain Status
| Status | Description |
|---|---|
pending | DNS records not yet verified |
verified | All DNS records verified, ready to send |
failed | Verification failed (records may be incorrect) |
List Domains
GET /v1/domainsconst { data } = await client.domains.list();
for (const domain of data) {
console.log(`${domain.domain}: ${domain.status}`);
}DMARC Configuration
DMARC (Domain-based Message Authentication, Reporting, and Conformance) is required by Google and Yahoo for bulk senders. It builds on SPF and DKIM to prevent spoofing.
Getting Started
Add a TXT record for _dmarc.yourdomain.com with a monitoring-only policy to start:
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.comProgressive Enforcement
After monitoring reports for a few weeks and confirming SPF/DKIM alignment, progress to stricter policies:
| Policy | Record | Behavior |
|---|---|---|
| p=none | v=DMARC1; p=none; rua=mailto:... | Monitor only, no action on failures |
| p=quarantine | v=DMARC1; p=quarantine; rua=mailto:... | Move failing emails to spam |
| p=reject | v=DMARC1; p=reject; rua=mailto:... | Reject failing emails entirely |
SPF and DKIM Alignment
DMARC requires either SPF or DKIM to pass and align with the "From" domain. Verify your domain in Veil Mail first to ensure DKIM is configured, then add your DMARC record.
Tracking Configuration
Control open and click tracking per domain. Both are enabled by default. Disabling tracking will prevent the email provider from injecting tracking pixels (opens) or rewriting links (clicks) for emails sent from this domain.
PATCH /v1/domains/:id// Disable open tracking, keep click tracking enabled
const domain = await client.domains.update('domain_xxxxx', {
trackOpens: false,
trackClicks: true,
});
console.log(domain.tracking);
// { opens: false, clicks: true }Response
All domain responses include a tracking object:
{
"id": "domain_xxxxx",
"domain": "mail.example.com",
"status": "verified",
"tracking": {
"opens": false,
"clicks": true
},
"dnsHealth": {
"healthy": true,
"issues": [],
"lastCheckedAt": "2025-01-15T16:00:00Z"
},
"verifiedAt": "2025-01-15T10:00:00Z",
"createdAt": "2025-01-10T10:00:00Z"
}Python SDK
domain = client.domains.update(
"domain_xxxxx",
track_opens=False,
track_clicks=True,
)
print(domain["tracking"])
# {"opens": False, "clicks": True}DNS Health Monitoring
Veil Mail automatically monitors DNS records for all verified domains every 6 hours. If records change or disappear, the domain's health status is updated and visible in the dashboard and API responses.
Health Status
All domain responses include a dnsHealth object:
| Field | Type | Description |
|---|---|---|
| healthy | boolean | Whether all required DNS records are valid |
| issues | string[] | List of detected DNS issues (empty when healthy) |
| lastCheckedAt | string | null | ISO timestamp of the last health check |
const domain = await client.domains.get('domain_xxxxx');
if (!domain.dnsHealth.healthy) {
console.warn('DNS issues:', domain.dnsHealth.issues);
// ["DKIM record not found at veil._domainkey.mail.example.com"]
}BIMI (Brand Indicators for Message Identification)
BIMI allows your brand logo to appear next to your emails in supported email clients (Gmail, Apple Mail, Yahoo). When recipients see your verified logo, it builds trust and increases engagement.
Prerequisites
- DMARC enforcement - Your domain must have a DMARC policy of
p=quarantineorp=reject - Brand logo - An SVG file in Tiny P/S format, hosted at a public HTTPS URL
- VMC (optional) - A Verified Mark Certificate from DigiCert or Entrust for Gmail support
DNS Record Format
Add a TXT record at default._bimi.yourdomain.com:
v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem| Tag | Required | Description |
|---|---|---|
| v=BIMI1 | Yes | BIMI version identifier |
| l= | Yes | HTTPS URL to your brand logo (SVG Tiny P/S format) |
| a= | No | HTTPS URL to your Verified Mark Certificate (VMC) |
Check BIMI Status
GET /v1/domains/:id/bimiconst bimi = await client.domains.checkBimi('domain_xxxxx');
if (bimi.bimi.configured) {
console.log('Logo URL:', bimi.bimi.logoUrl);
console.log('VMC URL:', bimi.bimi.authorityUrl);
} else {
console.log('BIMI not configured:', bimi.errors);
}Response
{
"domainId": "domain_xxxxx",
"domain": "mail.example.com",
"bimi": {
"configured": true,
"logoUrl": "https://example.com/logo.svg",
"authorityUrl": "https://example.com/vmc.pem",
"rawRecord": "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem"
},
"dnsRecord": {
"type": "TXT",
"name": "default._bimi.mail.example.com",
"expectedFormat": "v=BIMI1; l=<logo_url>; a=<authority_url>"
},
"errors": []
}BIMI status is also included in all domain list and detail responses under the bimi field, and is automatically re-checked during periodic DNS health monitoring.
SVG Requirements
The logo must be in SVG Tiny P/S (Portable/Secure) format — not standard SVG. Many email clients reject logos that do not meet this specification. Use a tool like the BIMI Group SVG converter to validate your file.
Link Branding (Custom Tracking Domains)
By default, click and open tracking links use Veil Mail's domain. Link branding lets you replace those with your own custom domain (e.g., track.yourdomain.com), improving deliverability and maintaining a consistent brand experience for recipients.
Why Use Link Branding?
- Better deliverability - Links from your own domain are less likely to be flagged by spam filters
- Brand consistency - Recipients see your domain in tracking links, not a third-party URL
- Recipient trust - Users are more likely to click links that match your brand
Step 1: Set Your Tracking Domain
POST /v1/domains/:id/tracking-domainconst result = await client.domains.setTrackingDomain('domain_xxxxx', {
trackingDomain: 'track.example.com',
});
console.log(result.dnsInstructions);
// { type: 'CNAME', name: 'track.example.com', value: 'track.veilmail.xyz' }Step 2: Configure DNS
Add a CNAME record at your DNS provider:
| Type | Host | Value |
|---|---|---|
| CNAME | track | track.veilmail.xyz |
Step 3: Verify
POST /v1/domains/:id/tracking-domain/verifyconst result = await client.domains.verifyTrackingDomain('domain_xxxxx');
if (result.trackingDomain.verified) {
console.log('Tracking domain verified!');
// All click/open tracking links will now use track.example.com
} else {
console.log('Errors:', result.errors);
}Remove Tracking Domain
DELETE /v1/domains/:id/tracking-domainawait client.domains.removeTrackingDomain('domain_xxxxx');
// Tracking links will revert to using the default Veil Mail domainResponse
All domain responses now include a trackingDomain object:
{
"id": "domain_xxxxx",
"domain": "mail.example.com",
"status": "verified",
"trackingDomain": {
"domain": "track.example.com",
"verified": true,
"cname": "track.veilmail.xyz"
},
...
}SSL Certificates
Custom tracking domains require SSL/TLS. Veil Mail automatically provisions certificates for verified tracking domains. Allow a few minutes after verification for certificate provisioning to complete.
Delete Domain
DELETE /v1/domains/:idawait client.domains.delete('domain_xxxxx');