Email deliverability audit skill

Diagnostic audit for a running cold email program.

by growthenginenowoslawski·MIT license·★ 736 Stars on the repo·GitHub ↗

Use now

Files of Email deliverability audit

growthenginenowoslawski/main1 file shown
SKILL.md
Show the full text284 lines

Email Deliverability Audit

If your positive reply rate is dropping and you don't know why, start here. Most of the time the problem is deliverability — your emails aren't reaching inboxes. This skill tells you what's broken.

What it checks

Layer What How
DNS auth SPF, DKIM, DMARC present on each sending domain dig commands
Inbox health Warmup status, reputation, blocks, connection failures Smartlead email-accounts API
Volume health Daily sent trending, capacity utilization Smartlead analytics
Send + reply rate per inbox Sent count, reply count, reply rate % over lookback period Smartlead campaign analytics
Bounce rate Per-inbox and per-domain bounce rate over last 30 days Smartlead campaign analytics
Spam placement Real inbox-vs-spam test via Smartlead Smart Delivery optional

The 1% rule — and the floors that gate it

A healthy domain replies at 1% or better after 200 emails sent. Below 1% on a fair sample, something is broken, and if it stays broken the domain gets cancelled.

The 1% rule is one number: the same 1% that flags a domain here is the line that retires it in /inbox-lifecycle-manager. What separates "flag" from "cancel" is not a softer second threshold — it is the floors. Below a floor, the answer is "we don't know yet", which is a legitimate output rather than a failure.

Judgment Floor before it counts
Reply rate 200 sends in the window
Bounce rate 50 sends
Bounce composition (which bucket) 30 classified bounces for that domain
Any cancel decision 30 days of domain age; unknown age counts as young
Placement test 100-300 senders per test

Reporting 0.00% reply on 14 sends as a failure, or condemning a three-week-old domain that has not finished ramping, is how healthy domains get killed.

Reply rate (≥200 sends) Reading
≥ 1.5% Genuinely good. Leave it alone.
1.0 - 1.5% Healthy. The rule passes.
< 1.0% Burned. Hand to /inbox-lifecycle-manager — but only if it also clears the 200-send and 30-day floors.
0 replies on ≥150 sends Decisive. A flat zero needs less sample than a low-but-nonzero rate.

Possible causes when a domain is below the line (the audit's root-cause suggestions try to pinpoint which):

  • Emails landing in spam — run the spam placement test
  • Domain reputation damaged — check DMARC reports and the bounce codes
  • Copy is broken — re-run /spam-word-checker; confirm with a control-fleet placement test
  • List is cold or wrong ICP — check bounce rate; if >3%, the list is the problem, not the domain
  • Inbox hasn't warmed enough — check warmup status and domain age
The domain-vs-copy isolation test

Low placement alone does not tell you whether the domain is burned or the copy is toxic. Run the same copy from a known-good control fleet:

Your fleet Control fleet Verdict
< 100% ~100% Domain-side. Your sending infrastructure is the problem.
< 100% < 100% Copy. Rewrite before you replace a single domain.
≥ 85% ≥ 85% Neither. Infrastructure is fine — this is targeting or offer.
control untestable — Assume copy. It is cheaper to fix and reversible.

When to use

  • Reply rate dropped by >30% week-over-week → run the full audit
  • Bounces spiked above 2% → run auth + spam-placement checks
  • Before scaling a campaign (make sure infrastructure is ready)
  • Monthly as routine hygiene
  • When taking over a Smartlead account you didn't set up

Inputs

  • SMARTLEAD_API_KEY (env)
  • Optional: scope the audit
    • --client-id=X (for sub-clients)
    • --campaign-id=X (audit only one campaign's inboxes)
    • --domain=example.com (audit only one domain)
    • --tag=active (audit only inboxes tagged active)

Steps

1. Pull the inbox inventory
npx tsx scripts/audit-inboxes.ts --all --out=/tmp/audit/inboxes.csv

Outputs per inbox: id, email, domain, warmup_status, reputation, max_warmup/day, sent_today, smtp_ok, imap_ok, is_blocked, tags.

2. Check domain authentication
npx tsx scripts/check-domain-auth.ts --from-csv=/tmp/audit/inboxes.csv --out=/tmp/audit/auth.csv

For each unique domain, runs:

dig TXT <domain> +short                             # SPF
dig TXT _dmarc.<domain> +short                      # DMARC

# DKIM has NO single selector. Present if ANY of these resolves:
dig TXT   google._domainkey.<domain>    +short      # Google / Gmail-backed — the common one
dig CNAME selector1._domainkey.<domain> +short      # Microsoft 365 — a CNAME, TXT returns nothing
dig CNAME selector2._domainkey.<domain> +short      # Microsoft 365, second key
dig TXT   default._domainkey.<domain>   +short      # generic fallback, frequently empty

⛔ Never check default._domainkey alone. It is empty on most real fleets, and a default-only check reports every domain as "missing DKIM" — which routes genuinely burned domains to "fix your DNS" and wastes a week republishing records that already exist. The script tries all four and reports which one resolved.

Outputs: domain, spf_present, spf_strict, dkim_present, dmarc_present, dmarc_policy (none/quarantine/reject).

3. Pull sent + reply + bounce metrics per campaign/inbox
npx tsx scripts/audit-performance.ts --days=30 --out=/tmp/audit/performance.csv

Walks all active campaigns, pulls per-inbox analytics for the last 30 days. Output columns: inbox_id, email, domain, type, tags, sent, replies, bounces, reply_rate_pct, bounce_rate_pct, flag_low_reply, flag_high_bounce.

Flagged automatically:

  • flag_low_reply = TRUE if sent ≥200 and reply_rate_pct < 1.0 (the 1% rule)
  • flag_high_bounce = TRUE if sent ≥50 and bounce_rate_pct > 3.0
4. (Optional) Run a Smart Delivery spam placement test
npx tsx scripts/run-spam-test.ts --campaign-id=12345 --senders=100 --out=/tmp/audit/spam-test.json

This creates a real inbox-placement test via Smartlead's Smart Delivery API:

  • Uses the only available provider pools: G Suite + Office365 (provider_ids 20, 21)
  • Sends to ~200 seed mailboxes with 100 of your senders
  • Waits for completion (5-20 min)
  • Pulls: providerwise, spam-filter-details, dkim-details, spf-details, blacklist

Output shows: what % lands in Inbox vs Spam vs Promotions, broken down by your sender and the receiver provider. This is the ground truth.

5. Synthesize the report
npx tsx scripts/generate-report.ts --audit-dir=/tmp/audit --out=/tmp/audit/report.md

Produces a markdown report like:

# Deliverability Audit — 2026-04-17

## Summary

- 80 inboxes audited across 40 domains
- 3 inboxes blocked (4% of fleet)
- 5 domains missing DKIM
- 2 domains with DMARC policy=none (no enforcement)
- Fleet performance (last 30d):
    Sent:           42,384
    Replies:          523
    Overall reply rate: 1.23% (PASS — above 1% threshold)
    Bounces:           382
    Bounce rate:      0.90% (PASS — below 2%)
- 4 inboxes failed the 1% rule (sent ≥200, reply rate <1%)
- Spam placement (test run): 83% inbox / 14% spam / 3% tabs (ACCEPTABLE but not great)

## Critical issues (fix within 24h)

1. Domain trygrowth.co has no DMARC record. Add: v=DMARC1; p=none; rua=mailto:[email protected]
2. Inbox [email protected] blocked in warmup — likely flagged by warmup network. Rotate out of campaigns.
3. 12 inboxes have 0 daily sent today despite being in active campaigns. Check campaign schedule.
4. Inbox [email protected] failed the 1% rule: 347 sent, 1 reply (0.29% reply rate). Investigate:
   - Check spam placement for this inbox
   - Compare copy vs. a sibling inbox that's passing
   - Rotate inbox out if bad reputation is confirmed

## Warnings (fix within 1 week)

- 5 domains missing DKIM record at default._domainkey
- 3 inboxes reputation dropped "fair" → "bad"
- Spam filter trigger DKIM_INVALID firing 8% of the time — likely for a subset of domains

## Action items (prioritized)

1. [HIGH] Add missing DKIM records to: trygrowth.co, othergrow.co, ...
2. [HIGH] Rotate out blocked inboxes: [email protected], [email protected], ...
3. [MED] Tighten DMARC to p=quarantine on all domains after 2 weeks of p=none observation
4. [MED] Replace 3 bad-reputation inboxes (tag them "retired", provision new)
5. [LOW] Re-run spam placement test after fixing DKIM issues
6. Act on the action items

Feed the action items into the right skills:

  • Missing DKIM / SPF → /zapmail-domain-setup-public to reconnect domains through Zapmail
  • Blocked inboxes → /smartlead-inbox-manager to tag "retired" and rotate in insurance
  • Campaign schedule issues → Smartlead campaign schedule settings
  • Bad copy flagged → /spam-word-checker on the campaign copy

Interpreting the numbers

Bounce rates
  • <1% — Excellent. Healthy list.
  • 1-2% — Normal for cold. No action.
  • 2-3% — Yellow. Check list quality, might be old emails.
  • >3% — Red. Verify the list (MillionVerifier), consider pausing.
  • >5% — Stop immediately. You're damaging domain reputation.
Spam placement
  • >90% inbox — Great. Ship more.
  • 85-90% inbox — Healthy. This is the line a domain must clear to be considered good metal.
  • 70-84% inbox — Degraded. Look at spam-filter-details to see what's triggering.
  • <70% inbox — Red, and a hard gate: do not attach this domain to a campaign. Pause and fix auth + copy before sending more.

Test with 100-300 senders. Smaller samples swing by double digits run to run.

DMARC policies
  • None — Acceptable for first 2 weeks of a domain's life. After that, tighten.
  • Quarantine — Recommended long-term. Emails that fail auth land in spam.
  • Reject — Strictest. Only use after 30+ days of clean rua= reports confirming all legitimate mail passes.
Warmup reputation
  • Smartlead reports reputation as 0-100. Higher is better.
  • ≥98% — required before promoting a reserve inbox into a live campaign.
  • 80-98% — sending is fine, but don't promote fresh reserves at this level.
  • 50-80% — keep warming, don't use for critical sends.
  • <50% — don't send from this inbox; warmup peers aren't seeing it in their inboxes.

⚠️ Warmup switched OFF is not a reputation of zero — it is no reading at all. An inbox with warmup off reports nothing, so it cannot be evaluated. Treat it as held: out of capacity, not attached to campaigns, reported for a human. Do not silently turn warmup back on to make a number appear — that rewrites the signal you are trying to measure.

Common root causes

  • SPF too lax — v=spf1 +all whitelists everyone. Use v=spf1 include:zapmail.com ~all or similar.
  • DKIM missing — new domain, selector not published. Zapmail publishes at default._domainkey by default.
  • DMARC alignment failure — From-domain doesn't match SPF/DKIM domain. Usually a misconfigured reply-to or a 3rd-party sender.
  • Too many inboxes per domain — Gmail flags domains with >3-5 inboxes as suspicious. Keep it at 2-3/domain.
  • Judging a domain that is too young or too quiet — under 30 days old or under 200 sends, the numbers cannot distinguish a burned domain from an unlucky week. This is not a root cause; it is the absence of evidence, and it is the single most common way a healthy domain gets killed.
  • Aggressive warmup ramp — Jumping from 5 to 40/day in one week = flag. Ramp over 2-4 weeks.
  • Shared sending IP with spam traffic — Zapmail/most providers use shared pools. If someone else on your IP spammed, you suffer. Not much to do except wait for pool rotation.

What to do next

If any flag fired: /deliverability-incident-response → triage decision tree for whatever was flagged (low reply rate, high bounce, blocked inbox, etc).

If a domain is confirmed burned: /inbox-lifecycle-manager → the cancel/promote/buy decision, with the guards that stop you cancelling into a send shortfall.

If all clean: next Monday, run this again. This audit is the Monday task in /cold-email-weekly-rhythm.

Or wait: if you just applied fixes, wait 7 days then re-audit. Reputation changes propagate slowly.

  • /smartlead-inbox-manager — execute the action items (rotate, retag, warmup settings)
  • /zapmail-domain-setup-public — fix DNS/auth issues at the domain provider
  • /spam-word-checker — check copy for spam-triggering phrases
  • /deliverability-test-public — lighter-weight SMTP vs Gmail vs Outlook reply/bounce comparison
  • /inbox-lifecycle-manager — acts on the verdict: cancel, promote reserves, plan the buy

Scripts

  • scripts/audit-inboxes.ts — pull + format inbox inventory
  • scripts/check-domain-auth.ts — dig-based SPF/DKIM/DMARC checks
  • scripts/audit-performance.ts — per-inbox sent / replies / bounces / rates from campaign analytics (applies the 1% rule)
  • scripts/run-spam-test.ts — create + poll + pull Smart Delivery test
  • scripts/generate-report.ts — synthesize all CSVs into markdown report
  • scripts/_smart-delivery.ts — shared Smart Delivery API wrapper

References

  • references/smart-delivery-api.md — full endpoint reference for Smart Delivery
  • references/dns-records.md — SPF/DKIM/DMARC record templates + interpretation guide
1---
2name: email-deliverability-audit
3description: Diagnostic audit for a running cold email program. Checks domain authentication (SPF/DKIM/DMARC), inbox health/reputation from Smartlead, bounce rate by inbox type, and optionally runs a spam placement test via Smartlead's Smart Delivery API. Outputs markdown report + CSV with per-domain/per-inbox scores and concrete action items. Use when reply rates drop, when bounces spike, when onboarding someone else's account, or as a weekly/monthly health check.
4---
5 
6# Email Deliverability Audit
7 
8**If your positive reply rate is dropping and you don't know why, start here.** Most of the time the problem is deliverability — your emails aren't reaching inboxes. This skill tells you what's broken.
9 
10## What it checks
11 
12| Layer | What | How |
13|---|---|---|
14| DNS auth | SPF, DKIM, DMARC present on each sending domain | `dig` commands |
15| Inbox health | Warmup status, reputation, blocks, connection failures | Smartlead email-accounts API |
16| Volume health | Daily sent trending, capacity utilization | Smartlead analytics |
17| Send + reply rate per inbox | Sent count, reply count, reply rate % over lookback period | Smartlead campaign analytics |
18| Bounce rate | Per-inbox and per-domain bounce rate over last 30 days | Smartlead campaign analytics |
19| Spam placement | Real inbox-vs-spam test via Smartlead Smart Delivery | optional |
20 
21## The 1% rule — and the floors that gate it
22 
23**A healthy domain replies at 1% or better after 200 emails sent.** Below 1% on a fair sample,
24something is broken, and if it stays broken the domain gets cancelled.
25 
26The 1% rule is **one number**: the same 1% that flags a domain here is the line that retires it in
27`/inbox-lifecycle-manager`. What separates "flag" from "cancel" is not a softer second threshold —
28it is the **floors**. Below a floor, the answer is "we don't know yet", which is a legitimate
29output rather than a failure.
30 
31| Judgment | Floor before it counts |
32|---|---|
33| Reply rate | **200 sends** in the window |
34| Bounce rate | **50 sends** |
35| Bounce *composition* (which bucket) | **30 classified bounces for that domain** |
36| Any cancel decision | **30 days of domain age**; unknown age counts as young |
37| Placement test | 100-300 senders per test |
38 
39Reporting `0.00% reply` on 14 sends as a failure, or condemning a three-week-old domain that has
40not finished ramping, is how healthy domains get killed.
41 
42| Reply rate (≥200 sends) | Reading |
43|---|---|
44| **≥ 1.5%** | Genuinely good. Leave it alone. |
45| **1.0 - 1.5%** | Healthy. The rule passes. |
46| **< 1.0%** | Burned. Hand to `/inbox-lifecycle-manager` — but only if it also clears the 200-send and 30-day floors. |
47| **0 replies on ≥150 sends** | Decisive. A flat zero needs less sample than a low-but-nonzero rate. |
48 
49Possible causes when a domain is below the line (the audit's root-cause suggestions try to
50pinpoint which):
51- Emails landing in spam — run the spam placement test
52- Domain reputation damaged — check DMARC reports and the bounce codes
53- Copy is broken — re-run `/spam-word-checker`; confirm with a control-fleet placement test
54- List is cold or wrong ICP — check bounce rate; if >3%, the list is the problem, not the domain
55- Inbox hasn't warmed enough — check warmup status and domain age
56 
57### The domain-vs-copy isolation test
58 
59Low placement alone does not tell you whether the domain is burned or the copy is toxic. Run the
60same copy from a known-good control fleet:
61 
62| Your fleet | Control fleet | Verdict |
63|---|---|---|
64| < 100% | ~100% | **Domain-side.** Your sending infrastructure is the problem. |
65| < 100% | < 100% | **Copy.** Rewrite before you replace a single domain. |
66| ≥ 85% | ≥ 85% | Neither. Infrastructure is fine — this is targeting or offer. |
67| control untestable | — | Assume copy. It is cheaper to fix and reversible. |
68 
69## When to use
70 
71- Reply rate dropped by >30% week-over-week → run the full audit
72- Bounces spiked above 2% → run auth + spam-placement checks
73- Before scaling a campaign (make sure infrastructure is ready)
74- Monthly as routine hygiene
75- When taking over a Smartlead account you didn't set up
76 
77## Inputs
78 
79- `SMARTLEAD_API_KEY` (env)
80- Optional: scope the audit
81 - `--client-id=X` (for sub-clients)
82 - `--campaign-id=X` (audit only one campaign's inboxes)
83 - `--domain=example.com` (audit only one domain)
84 - `--tag=active` (audit only inboxes tagged active)
85 
86## Steps
87 
88### 1. Pull the inbox inventory
89 
90```bash
91npx tsx scripts/audit-inboxes.ts --all --out=/tmp/audit/inboxes.csv
92```
93 
94Outputs per inbox: id, email, domain, warmup_status, reputation, max_warmup/day, sent_today, smtp_ok, imap_ok, is_blocked, tags.
95 
96### 2. Check domain authentication
97 
98```bash
99npx tsx scripts/check-domain-auth.ts --from-csv=/tmp/audit/inboxes.csv --out=/tmp/audit/auth.csv
100```
101 
102For each unique domain, runs:
103```bash
104dig TXT <domain> +short # SPF
105dig TXT _dmarc.<domain> +short # DMARC
106 
107# DKIM has NO single selector. Present if ANY of these resolves:
108dig TXT google._domainkey.<domain> +short # Google / Gmail-backed — the common one
109dig CNAME selector1._domainkey.<domain> +short # Microsoft 365 — a CNAME, TXT returns nothing
110dig CNAME selector2._domainkey.<domain> +short # Microsoft 365, second key
111dig TXT default._domainkey.<domain> +short # generic fallback, frequently empty
112```
113 
114⛔ **Never check `default._domainkey` alone.** It is empty on most real fleets, and a
115`default`-only check reports every domain as "missing DKIM" — which routes genuinely burned
116domains to "fix your DNS" and wastes a week republishing records that already exist. The script
117tries all four and reports which one resolved.
118 
119Outputs: domain, spf_present, spf_strict, dkim_present, dmarc_present, dmarc_policy (none/quarantine/reject).
120 
121### 3. Pull sent + reply + bounce metrics per campaign/inbox
122 
123```bash
124npx tsx scripts/audit-performance.ts --days=30 --out=/tmp/audit/performance.csv
125```
126 
127Walks all active campaigns, pulls per-inbox analytics for the last 30 days. Output columns: `inbox_id, email, domain, type, tags, sent, replies, bounces, reply_rate_pct, bounce_rate_pct, flag_low_reply, flag_high_bounce`.
128 
129Flagged automatically:
130- **`flag_low_reply = TRUE`** if sent ≥200 and reply_rate_pct < 1.0 (the 1% rule)
131- **`flag_high_bounce = TRUE`** if sent ≥50 and bounce_rate_pct > 3.0
132 
133### 4. (Optional) Run a Smart Delivery spam placement test
134 
135```bash
136npx tsx scripts/run-spam-test.ts --campaign-id=12345 --senders=100 --out=/tmp/audit/spam-test.json
137```
138 
139This creates a real inbox-placement test via Smartlead's Smart Delivery API:
140- Uses the only available provider pools: G Suite + Office365 (provider_ids 20, 21)
141- Sends to ~200 seed mailboxes with 100 of your senders
142- Waits for completion (5-20 min)
143- Pulls: providerwise, spam-filter-details, dkim-details, spf-details, blacklist
144 
145Output shows: what % lands in Inbox vs Spam vs Promotions, broken down by your sender and the receiver provider. This is the ground truth.
146 
147### 5. Synthesize the report
148 
149```bash
150npx tsx scripts/generate-report.ts --audit-dir=/tmp/audit --out=/tmp/audit/report.md
151```
152 
153Produces a markdown report like:
154 
155```
156# Deliverability Audit — 2026-04-17
157 
158## Summary
159 
160- 80 inboxes audited across 40 domains
161- 3 inboxes blocked (4% of fleet)
162- 5 domains missing DKIM
163- 2 domains with DMARC policy=none (no enforcement)
164- Fleet performance (last 30d):
165 Sent: 42,384
166 Replies: 523
167 Overall reply rate: 1.23% (PASS — above 1% threshold)
168 Bounces: 382
169 Bounce rate: 0.90% (PASS — below 2%)
170- 4 inboxes failed the 1% rule (sent ≥200, reply rate <1%)
171- Spam placement (test run): 83% inbox / 14% spam / 3% tabs (ACCEPTABLE but not great)
172 
173## Critical issues (fix within 24h)
174 
1751. Domain trygrowth.co has no DMARC record. Add: v=DMARC1; p=none; rua=mailto:[email protected]
1762. Inbox [email protected] blocked in warmup — likely flagged by warmup network. Rotate out of campaigns.
1773. 12 inboxes have 0 daily sent today despite being in active campaigns. Check campaign schedule.
1784. Inbox [email protected] failed the 1% rule: 347 sent, 1 reply (0.29% reply rate). Investigate:
179 - Check spam placement for this inbox
180 - Compare copy vs. a sibling inbox that's passing
181 - Rotate inbox out if bad reputation is confirmed
182 
183## Warnings (fix within 1 week)
184 
185- 5 domains missing DKIM record at default._domainkey
186- 3 inboxes reputation dropped "fair" → "bad"
187- Spam filter trigger DKIM_INVALID firing 8% of the time — likely for a subset of domains
188 
189## Action items (prioritized)
190 
1911. [HIGH] Add missing DKIM records to: trygrowth.co, othergrow.co, ...
1922. [HIGH] Rotate out blocked inboxes: [email protected], [email protected], ...
1933. [MED] Tighten DMARC to p=quarantine on all domains after 2 weeks of p=none observation
1944. [MED] Replace 3 bad-reputation inboxes (tag them "retired", provision new)
1955. [LOW] Re-run spam placement test after fixing DKIM issues
196```
197 
198### 6. Act on the action items
199 
200Feed the action items into the right skills:
201- Missing DKIM / SPF → `/zapmail-domain-setup-public` to reconnect domains through Zapmail
202- Blocked inboxes → `/smartlead-inbox-manager` to tag "retired" and rotate in insurance
203- Campaign schedule issues → Smartlead campaign schedule settings
204- Bad copy flagged → `/spam-word-checker` on the campaign copy
205 
206## Interpreting the numbers
207 
208### Bounce rates
209- **<1%** — Excellent. Healthy list.
210- **1-2%** — Normal for cold. No action.
211- **2-3%** — Yellow. Check list quality, might be old emails.
212- **>3%** — Red. Verify the list (MillionVerifier), consider pausing.
213- **>5%** — Stop immediately. You're damaging domain reputation.
214 
215### Spam placement
216- **>90% inbox** — Great. Ship more.
217- **85-90% inbox** — Healthy. This is the line a domain must clear to be considered good metal.
218- **70-84% inbox** — Degraded. Look at spam-filter-details to see what's triggering.
219- **<70% inbox** — Red, and a hard gate: do not attach this domain to a campaign. Pause and fix
220 auth + copy before sending more.
221 
222Test with 100-300 senders. Smaller samples swing by double digits run to run.
223 
224### DMARC policies
225- **None** — Acceptable for first 2 weeks of a domain's life. After that, tighten.
226- **Quarantine** — Recommended long-term. Emails that fail auth land in spam.
227- **Reject** — Strictest. Only use after 30+ days of clean `rua=` reports confirming all legitimate mail passes.
228 
229### Warmup reputation
230- Smartlead reports reputation as 0-100. Higher is better.
231- **≥98%** — required before promoting a reserve inbox into a live campaign.
232- **80-98%** — sending is fine, but don't promote fresh reserves at this level.
233- **50-80%** — keep warming, don't use for critical sends.
234- **<50%** — don't send from this inbox; warmup peers aren't seeing it in their inboxes.
235 
236⚠️ **Warmup switched OFF is not a reputation of zero — it is no reading at all.** An inbox with
237warmup off reports nothing, so it cannot be evaluated. Treat it as **held**: out of capacity, not
238attached to campaigns, reported for a human. Do not silently turn warmup back on to make a number
239appear — that rewrites the signal you are trying to measure.
240 
241## Common root causes
242 
243- **SPF too lax** — `v=spf1 +all` whitelists everyone. Use `v=spf1 include:zapmail.com ~all` or similar.
244- **DKIM missing** — new domain, selector not published. Zapmail publishes at `default._domainkey` by default.
245- **DMARC alignment failure** — From-domain doesn't match SPF/DKIM domain. Usually a misconfigured reply-to or a 3rd-party sender.
246- **Too many inboxes per domain** — Gmail flags domains with >3-5 inboxes as suspicious. Keep it at 2-3/domain.
247- **Judging a domain that is too young or too quiet** — under 30 days old or under 200 sends, the
248 numbers cannot distinguish a burned domain from an unlucky week. This is not a root cause; it is
249 the absence of evidence, and it is the single most common way a healthy domain gets killed.
250- **Aggressive warmup ramp** — Jumping from 5 to 40/day in one week = flag. Ramp over 2-4 weeks.
251- **Shared sending IP with spam traffic** — Zapmail/most providers use shared pools. If someone else on your IP spammed, you suffer. Not much to do except wait for pool rotation.
252 
253## What to do next
254 
255**If any flag fired:** `/deliverability-incident-response` → triage decision tree for whatever was flagged (low reply rate, high bounce, blocked inbox, etc).
256 
257**If a domain is confirmed burned:** `/inbox-lifecycle-manager` → the cancel/promote/buy decision, with the guards that stop you cancelling into a send shortfall.
258 
259**If all clean:** next Monday, run this again. This audit is the Monday task in `/cold-email-weekly-rhythm`.
260 
261**Or wait:** if you just applied fixes, wait 7 days then re-audit. Reputation changes propagate slowly.
262 
263## Related skills
264 
265- `/smartlead-inbox-manager` — execute the action items (rotate, retag, warmup settings)
266- `/zapmail-domain-setup-public` — fix DNS/auth issues at the domain provider
267- `/spam-word-checker` — check copy for spam-triggering phrases
268- `/deliverability-test-public` — lighter-weight SMTP vs Gmail vs Outlook reply/bounce comparison
269- `/inbox-lifecycle-manager` — acts on the verdict: cancel, promote reserves, plan the buy
270 
271## Scripts
272 
273- `scripts/audit-inboxes.ts` — pull + format inbox inventory
274- `scripts/check-domain-auth.ts` — dig-based SPF/DKIM/DMARC checks
275- `scripts/audit-performance.ts` — per-inbox sent / replies / bounces / rates from campaign analytics (applies the 1% rule)
276- `scripts/run-spam-test.ts` — create + poll + pull Smart Delivery test
277- `scripts/generate-report.ts` — synthesize all CSVs into markdown report
278- `scripts/_smart-delivery.ts` — shared Smart Delivery API wrapper
279 
280## References
281 
282- `references/smart-delivery-api.md` — full endpoint reference for Smart Delivery
283- `references/dns-records.md` — SPF/DKIM/DMARC record templates + interpretation guide
284 

Discussion

Alternatives