Deliverability skill

SPF, DKIM and DMARC audit for sending domains

Give the assistant your sending domains and it reads SPF, DKIM, DMARC and MX the way a receiving server does, then returns a pass/fail table per domain with the exact records to publish.

Works with

One Markdown file, free to use and change. It reads only what you paste into the chat.

What it does

What the skill checks

  • Finds duplicate SPF records and counts SPF DNS lookups against the limit of 10
  • Checks that every service sending as the domain is covered by SPF and DKIM
  • Checks DKIM key length and empty or revoked keys per selector
  • Checks DMARC policy, reporting address and alignment with the From domain
  • Checks MX records and the custom tracking domain
  • Compares the setup with the public Google and Yahoo sender requirements

Use it when

  • When you set up new sending domains and mailboxes
  • When mail starts failing authentication or landing in spam
  • When you add a new tool that sends email as your domain

Example

What you paste and what you get back

You
Audit example.com. We send from Google Workspace and a sequencer. TXT shows two v=spf1 records and there is no _dmarc record.
Assistant, with the skill
SPF single record: FAIL. Two v=spf1 records cause a permerror. Merge into: v=spf1 include:_spf.google.com include:sendgrid.net ~all
SPF lookups: PASS (4 of 10)
DKIM selector google: PASS, 2048-bit key
DMARC: FAIL, no record. Publish TXT at _dmarc: v=DMARC1; p=none; rua=mailto:dmarc@example.com
MX: PASS
Google and Yahoo requirements: not met until DMARC is published.

Install

Install it in your assistant

The same file works everywhere. Claude and Claude Code load it as a skill; the other assistants follow it as instructions.

Claude Code

  1. Run the command below. It saves the skill to your personal skills folder, available in every project. For one project only, use .claude/skills in the project instead.
  2. Start a new Claude Code session. Claude uses the skill when your request matches its description, or when you name it.
Terminal
mkdir -p ~/.claude/skills/email-dns-audit
curl -fsSL https://outreach2day.com/skills/email-dns-audit/SKILL.md -o ~/.claude/skills/email-dns-audit/SKILL.md

Claude (web and desktop)

  1. Download the ZIP file.
  2. In Claude, open Settings, find Skills under Capabilities and upload the ZIP. Skills need code execution to be turned on for your account.
  3. Ask for the task in any chat. Claude loads the skill when the request matches.

ChatGPT

  1. Download SKILL.md.
  2. Paste its text into a Project's instructions or a custom GPT's instructions. For a single chat, attach the file and write: follow the instructions in this file.

Gemini

  1. Download SKILL.md.
  2. Create a Gem and paste the file's text into its instructions, or attach the file to a chat and ask Gemini to follow it.

Grok

  1. Download SKILL.md.
  2. Paste its text into a Project's instructions, or attach the file to a chat and ask Grok to follow it.

Cursor and other coding agents

  1. Save the file as a project rule with the command below. Cursor reads the description to decide when to apply it.
  2. Agents that read AGENTS.md (Codex and others): paste the text into AGENTS.md or reference the file from it.
Terminal, in your project
mkdir -p .cursor/rules
curl -fsSL https://outreach2day.com/skills/email-dns-audit/SKILL.md -o .cursor/rules/email-dns-audit.mdc

Source

The full SKILL.md

Read it before you install it. Change the rules to match your own setup.

email-dns-audit/SKILL.md
---
name: email-dns-audit
description: Audits the email DNS of cold email sending domains - SPF, DKIM, DMARC, MX and the custom tracking domain - and returns a pass/fail table per domain with exact record fixes. Counts SPF DNS lookups, checks DKIM key length per sending service, checks DMARC policy, reporting and alignment with the From domain, and compares the setup with the public Google and Yahoo sender requirements. Use when the user shares domains or DNS records, asks why mail goes to spam or fails authentication, sets up new sending domains, or asks to check SPF, DKIM or DMARC.
---

# Email DNS audit for sending domains

You audit the DNS of each sending domain the way a receiving mail server reads it, and return one table per domain with the exact record to add or change. You never guess a record: you read it (or ask the user to paste it) before judging it.

## Step 1. Collect the records

For each domain, get these records. If you cannot run commands, ask the user to run them and paste the output.

```
dig +short TXT example.com                      # SPF lives here (v=spf1 ...)
dig +short TXT _dmarc.example.com               # DMARC
dig +short TXT <selector>._domainkey.example.com  # DKIM, one per selector
dig +short MX example.com
dig +short CNAME track.example.com              # custom tracking domain, if used
```

Without dig, use DNS over HTTPS:

```
curl -s -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=_dmarc.example.com&type=TXT'
```

Also ask: which services send mail as this domain (mailbox provider, sequencer, CRM, helpdesk, newsletter tool), and which DKIM selectors they use. Common selectors: `google`, `selector1`/`selector2` (Microsoft 365), `default`, `k1`, `s1`, `s2`, `dkim`, `mail`. The selector is in the `DKIM-Signature: ... s=` header of a sent message.

## Step 2. Check SPF

1. Exactly one TXT record starting with `v=spf1`. Two SPF records = permerror = SPF fails.
2. Every service that sends as the domain is covered by an `include:`, `ip4:` or `ip6:`.
3. At most 10 DNS lookups in total. Count `include`, `a`, `mx`, `ptr`, `exists`, `redirect`, and the lookups inside each include, recursively. Over 10 = permerror.
4. Ends with `~all` (softfail) or `-all` (fail). `?all` or `+all` = no protection; `+all` lets anyone send as you.
5. No `ptr` mechanism (deprecated, slow).
6. Record under 255 characters per string; longer records are split into quoted strings.

## Step 3. Check DKIM

1. A key exists for each sending service's selector.
2. Key length 2048 bits where the provider supports it (1024 still passes, but is weaker). A `p=` value of roughly 390+ base64 characters is 2048-bit.
3. `p=` is not empty (empty = revoked key).
4. The domain in the signature (`d=`) matches the From domain or its parent, so DMARC can align.

## Step 4. Check DMARC

1. Exactly one TXT record at `_dmarc.<domain>` starting with `v=DMARC1`.
2. Policy `p=`: `none` is fine for the first weeks while you read reports; move to `quarantine`, then `reject`, once all legitimate senders pass. For cold sending domains, `p=none` or `p=quarantine` is common; what matters most is that the record exists and aligns.
3. `rua=mailto:` set, so you receive aggregate reports.
4. Alignment: SPF passes with the envelope (Return-Path) domain, DKIM with `d=`. At least one of them must match the From domain (relaxed alignment = same organizational domain; strict `aspf=s`/`adkim=s` = exact match). No alignment = DMARC fail even when SPF and DKIM pass.

## Step 5. Check MX and tracking

1. MX records exist, so the domain can receive replies and bounces. A domain with no MX looks disposable.
2. If the sequencer uses open or click tracking, the tracking host is a CNAME on your own domain, not the tool's shared domain. Better for cold email: tracking off, no links.
3. The domain has a working website or a redirect to the main site (optional, but a dead domain looks worse).

## Step 6. Compare with public sender requirements

Google and Yahoo require bulk senders to have SPF and DKIM, a DMARC record (at least `p=none`) aligned with the From domain, one-click unsubscribe for marketing mail, and a spam complaint rate below 0.3% (target below 0.1%). Say which of these the domain meets.

## Output format

One table per domain:

| Check | Status | Found | Fix |
|---|---|---|---|
| SPF single record | PASS / FAIL / WARN | the record | exact new record |

Then a list of the exact DNS records to publish (type, host, value), in the order to apply them, and what to re-check after the change (DNS can take up to the record's TTL to update).

## Rules

- Quote records exactly as returned. Do not invent selectors or includes.
- If a check needs information you do not have (for example, which tools send mail), mark it `UNKNOWN` and say what to ask.
- DNS that passes does not mean mail lands in the inbox. Authentication is required, not sufficient. Point the user to an inbox placement test for that.

## Example

Input: `example.com`, sends from Google Workspace and a sequencer. TXT shows `v=spf1 include:_spf.google.com ~all` and `v=spf1 include:sendgrid.net ~all`. No `_dmarc` record.

Output (abridged):

| Check | Status | Found | Fix |
|---|---|---|---|
| SPF single record | FAIL | 2 v=spf1 records | merge: `v=spf1 include:_spf.google.com include:sendgrid.net ~all` |
| DMARC record | FAIL | none | `_dmarc` TXT `v=DMARC1; p=none; rua=mailto:dmarc@example.com` |
| DKIM google | PASS | 2048-bit key | none |

Download SKILL.md · Download ZIP

FAQ

Questions

What happens if a domain has two SPF records?

Receiving servers return a permanent error and treat SPF as failed. Merge every include into one v=spf1 record.

Which DMARC policy should a cold email domain use?

Start with p=none and a rua address so you receive reports. Move to quarantine once every legitimate sender passes. The record must exist and align with the From domain; Google and Yahoo require at least p=none for bulk senders.

How do I find my DKIM selector?

Open a sent email's headers and find DKIM-Signature. The s= value is the selector and d= is the signing domain. Google Workspace uses google by default, Microsoft 365 uses selector1 and selector2.

Can I check the records without an AI assistant?

Yes. The free SPF, DKIM and DMARC checker on this site looks up the records from your browser and flags the same problems.

Mailboxes, warm-up and sending in one place

$2.50 a mailbox a month. DNS records are set for you, and every mailbox shows its warm-up numbers from day one.