If your emails keep landing in spam and you're using Google Workspace… this article is written exactly for you.
Because let’s be real, setting up DKIM on Google Workspace is a nightmare.
There’s no API.
You have to log in to three different places.
You’re stuck copying TXT records and praying you did it right.
And if you mess it up?
You don’t get a warning. You just stop hitting the inbox.
I’ve been there.
So instead of guessing, I wrote this article to show you how to set up Google Workspace DKIM records automatically, with real code, actual scripts, and the exact API calls you’ll need.
You’ll get:
You’ll also learn how cold email tools like Mailforge handle all of this for you, no manual setup, no broken DNS records, just premium deliverability by default.
Ready to stop hoping and start hitting inboxes?
Let’s fix your setup.
DKIM (DomainKeys Identified Mail) is an email authentication method in Google Workspace that proves your emails came from your domain and weren’t tampered with in transit.
It helps inboxes like Gmail, Outlook, and Apple Mail trust your emails, so they land in Primary, not Spam.
If you’re sending cold emails and not using Google Workspace DKIM, you're doing all the work… for zero return.
Also Read: What are the 3 Best Email Service Providers (ESPs) for Cold Email?
It's a handshake between your domain and the inbox.
If the keys match? ✅ Inbox.
If they don’t? 🚫 Spam folder.
Just because your email shows as “delivered” doesn’t mean it hit the inbox.
Let me say that again:
Delivered ≠ Seen
You can have a 99% delivery rate and still end up in:
Without DKIM, you're invisible to the inbox.
With DKIM, you look legit—even at scale.
Setting up DKIM for Google Workspace is not optional.
It's the baseline for cold email deliverability, domain reputation, and actually getting replies.
If you’re sending cold emails without a properly configured DKIM, your emails are going straight to spam, and you’re wasting time, domains, and money.
Here’s the truth no one tells you:
Email deliverability is 80% setup, 20% copy.
Most founders and SDRs mess this up.
They launch a sequence, expect replies… and get none.
Why?
Because Gmail, Outlook, and Yahoo never even let their emails hit the inbox.
If you’re using Google Workspace for cold outreach and not setting up DKIM, you’re sending unsigned emails into a battlefield of spam filters.
These providers are ruthless.
DKIM tells inbox providers:
“This email is legit. It came from who it says it did. Don’t flag it.”
No DKIM = No trust = No inbox.
That’s the chain.
And look—doing it once isn’t enough.
You need automation to scale, rotate keys, and keep domains healthy as you grow.
How to Set Up Domain & Mailbox for Cold Email?
Before we dive into how to automate the DKIM setup step-by-step, let’s make sure you have the basic requirements ready to go.
Before you start coding or connecting APIs, you need to check four boxes.
Miss even one, and the whole automation stack breaks.
Your domain must already be added and verified in Google Workspace.
If Google doesn’t trust the domain, you can’t generate or manage DKIM at all.
You’ll need Super Admin rights.
This is the only way to manually generate the DKIM key (because yes—Google still makes you do this part manually).
You can’t automate DKIM without API access to your DNS zone.
This could be:
If your DNS provider doesn’t support API-based updates, you’re stuck doing it manually or switching providers.
For most users, Python is the easiest to get up and running.
You’ll need:
If you’re using Mailforge, you don’t need to write or manage any scripts. Just plug in your domains, and it handles DKIM, SPF, and DMARC out of the box.
Now that you’ve got everything lined up, let’s break down how to automate your DKIM setup—step by step.
You’re here because you don’t want to touch DNS manually every time.
Good. Let’s automate the boring stuff.
This 4-part workflow gets your Google Workspace DKIM set up with minimal manual effort.
Let’s get into it.
The first step is getting access to your Google Workspace account programmatically.
You’ll need a service account JSON file and these scopes:
SCOPES = ['https://www.googleapis.com/auth/admin.directory.domain.readonly']
Here’s your starter script:
from google.oauth2 import service_account
from googleapiclient.discovery import build
def initialize_admin_sdk():
credentials = service_account.Credentials.from_service_account_file(
'service-account.json',
scopes=SCOPES
)
service = build('admin', 'directory_v1', credentials=credentials)
return service
✅ What you can do with this:
❌ What you can’t do:
Now that you’re authenticated, here comes the one step you still have to do manually (for now).
There’s no way around this.
Google forces you to generate DKIM keys manually via the Admin Console.
Why?
Because they haven’t opened this feature to their API yet. Frustrating, but real.
Here’s how to do it:
💡 Pro Tip: Do this once per domain, then automate everything else moving forward.
Once you’ve got your DKIM key, it’s time to let the robots take over by automating your DNS update.
Now, take that DKIM TXT record and push it to your DNS provider using their API.
Example using Cloudflare API:
import requests
def update_dkim_dns(api_key, zone_id, dkim_record):
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
data = {
'type': 'TXT',
'name': 'google._domainkey',
'content': dkim_record,
'ttl': 3600
}
response = requests.post(
f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records',
headers=headers,
json=data
)
return response.json()
👨🔧 Adapting it to other providers:
Each DNS provider has their own API docs.
You’ll need credentials, zone ID, and endpoint structure. Use similar logic with AWS Route 53, GoDaddy, or Namecheap.
💣 TTL best practices:
Set a reasonable TTL (3600 = 1 hour). Too low = instability. Too high = long propagation delays.
🚨 Error handling:
Add retry logic and log failures. If your API call fails silently, your DKIM will never go live.
With your DKIM record now live in DNS, the last piece is verifying it actually works, before you start sending.
Just because you pushed a record doesn’t mean it’s live.
DNS takes time to propagate.
Here’s how to check it using dns.resolver:
import dns.resolver
def verify_dkim_record(domain, selector='google'):
try:
answers = dns.resolver.resolve(f'{selector}._domainkey.{domain}', 'TXT')
return any('v=DKIM1' in str(rdata) for rdata in answers)
except:
return False
⏳ Add retry logic:
Use exponential backoff and check every 5–10 minutes. Some providers take longer than others.
📬 Bonus: Send a test email to a Gmail or Outlook inbox
Open headers → Look for DKIM=pass
If it says “fail” or “neutral,” something’s broken.
So your DKIM setup is automated, but there are still places where things can break.
Let’s walk through the most common DKIM issues and how to fix them.
Even if you follow every step perfectly, the DKIM setup can still go sideways.
Here’s a breakdown of the most common problems—and exactly how to fix each one.
Cause:
Fix:
Cause:
Fix:
Cause:
Fix:
Cause:
Fix:
⚠ Bonus Tip: Add Logging and Monitoring Early
Don’t wait for emails to land in spam before checking DKIM health.
Log every automation step, and set alerts for failures or missing records.
Now that you know what to watch out for, let’s walk through the best practices to keep your DKIM setup rock solid, especially if you're scaling across multiple domains.
Here’s how to protect your setup, reputation, and sanity.
Why?
Because stale keys become a security risk and eventually get flagged by inbox providers.
Best practice:
What gets monitored gets managed.
DKIM can break silently, especially when teams update DNS settings and forget to notify ops.
How to do it:
You can do this with your own scripts or use Mailforge, which includes automatic DNS monitoring and alerts when DKIM or SPF records break.
Your service account keys and DNS API tokens = gold.
One leak, and your domain’s a sitting duck for spoofing or takeover.
Do this:
You need a paper trail. Not just for debugging, but for growth.
If a domain starts failing, you want to know when, why, and what changed.
Track:
Now, if you're thinking, “This is a lot of moving parts,” you’re right.
Mailforge logs every change to your domain records, including DKIM propagation, key updates, and failures—no custom logging setup required.
Now, for teams managing 10+ domains or 50+ inboxes, Mailforge saves hours by automating DKIM, SPF, and DMARC with just a few clicks.
The Fastest Way? Use Mailforge for Instant DKIM Setup
Let’s be real, manual DKIM setup is a time sink.
You’re juggling:
That’s why most people give up, or worse, skip DKIM entirely and wonder why inbox placement tanks.
But here’s the shortcut:
The second you add a domain, Mailforge:
✅ Sets up DKIM, SPF, and DMARC
✅ Handles DNS records automatically
✅ Tracks your domain health
✅ Optimizes everything for cold email deliverability
✅ Works with any sending platform
(including Agent Frank by Salesforge, Smartlead, Instantly, or even your custom system)
Pair with Warmforge for automatic inbox warm-up or Primeforge for Google/MS365-native cold email setup if you’re scaling across corporate domains.
⏱️ Setup time: under 5 minutes
💸 Cost: ~$2 per mailbox
📈 Deliverability: Premium-grade, cold outreach ready
Do you still want to build your own automation flow? No problem.
Here’s a sample Python script that does 90% of it, minus the pain.
If you’re the type who likes building your own infrastructure, here’s your base script to automate everything after generating the DKIM key in Google Workspace.
This script will:
✅ Verify your domain
✅ Update your DNS with the DKIM record
✅ Check propagation
✅ Log the result
✅ Scale across multiple domains
Let’s go.
import requests, time, dns.resolver
from google.oauth2 import service_account
from googleapiclient.discovery import build
class DKIMAutomation:
def __init__(self, domain, zone_id, api_key, dkim_record):
self.domain = domain
self.zone_id = zone_id
self.api_key = api_key
self.dkim_record = dkim_record
self.admin_service = self.initialize_admin_sdk()
def initialize_admin_sdk(self):
SCOPES = ['https://www.googleapis.com/auth/admin.directory.domain.readonly']
credentials = service_account.Credentials.from_service_account_file(
'service-account.json', scopes=SCOPES
)
service = build('admin', 'directory_v1', credentials=credentials)
return service
def update_dns(self):
headers = {
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json'
}
data = {
'type': 'TXT',
'name': 'google._domainkey',
'content': self.dkim_record,
'ttl': 3600
}
url = f'https://api.cloudflare.com/client/v4/zones/{self.zone_id}/dns_records'
return requests.post(url, headers=headers, json=data).json()
def verify_dkim(self, retries=6, delay=60):
for _ in range(retries):
try:
answers = dns.resolver.resolve(f'google._domainkey.{self.domain}', 'TXT')
if any('v=DKIM1' in str(rdata) for rdata in answers):
return True
except:
pass
time.sleep(delay)
return False
This script is a great foundation, but building for scale means constant updates, error handling, and watching for Google or DNS API changes.
If that sounds like overkill for your team… again, Mailforge handles all of this automatically.
Have questions about Google Workspace DKIM setup?
You're not alone. Let's hit the most common ones founders ask (and answer them fast).
If you made it this far, you already know: setting up DKIM in Google Workspace is not impossible, it’s just annoyingly manual.
To recap what we covered:
Here’s the truth:
If you're sending cold emails and still doing DKIM by hand, you’re burning hours and risking your inbox rate every single day.
You can either:
❌ Keep logging into the Admin Console, copying TXT records, and debugging DNS…
Or
✅ Switch to Mailforge, where DKIM, SPF, and DMARC are done for you—automatically.
With Mailforge, you’re inbox-ready in under 5 minutes. No scripts. No guessing.
Just domains that hit Primary, even at scale.
👉 Get started with Mailforge now — and never touch a DNS dashboard again.