Domain reputation and IP reputation are independent signals that mailbox providers track and report separately — Google Postmaster Tools explicitly distinguishes them. A domain reputation hit means your content or authentication history is the problem; an IP reputation hit means the specific IP's sending behavior is the problem. If you only track a combined metric, you cannot determine whether to reconfigure content and authentication (domain issue) or rotate to a new IP (IP issue). Without separation, diagnosing and recovering from deliverability problems is guesswork that delays resolution and extends inbox-blocking.
Low because conflating domain and IP reputation metrics slows diagnosis and recovery time rather than causing immediate inbox failure, but the operational cost of undiagnosed reputation problems compounds over time.
Store domain and IP reputation as separate Prisma models, each with its own updatedAt and queryable by its identifier. Use this schema or equivalent in prisma/schema.prisma:
model DomainReputation {
id String @id @default(uuid())
domain String @unique
spamRate Float?
inboxRate Float?
dkimPassRate Float?
spfPassRate Float?
dmarcPassRate Float?
updatedAt DateTime @updatedAt
}
model IpReputation {
id String @id @default(uuid())
ipAddress String @unique
spamRate Float?
microsoftCategory String? // Green / Yellow / Red
lastChecked DateTime
updatedAt DateTime @updatedAt
}
Populate DomainReputation from Google Postmaster Tools and IpReputation from Microsoft SNDS on a daily cron. Alerting logic should query each table independently so a domain reputation alert does not suppress an IP reputation alert.
ID: deliverability-engineering.warmup-reputation.reputation-tracking-separation
Severity: low
What to look for: Count all reputation metric storage tables or objects. Check whether the system distinguishes between domain reputation and IP reputation as separate metrics. Look for database tables or objects that store reputation scores, complaint rates, or bounce rates indexed by both domain and IP address independently. Check if the code processes Google Postmaster Tools data (which reports domain reputation separately from IP reputation) and maps each to the correct entity.
Pass criteria: At least 2 separate storage entities exist for reputation metrics: one indexed by domain and one indexed by IP. The system can report the reputation status of a specific domain independent of which IP is currently sending for it.
Fail criteria: Reputation is tracked as a single combined metric with no separation of domain vs. IP, or reputation tracking does not exist at all.
Skip (N/A) when: The project has a single sending domain and single dedicated IP where conflation of domain and IP reputation is acceptable.
Detail on fail: "Reputation tracked as a single metric with no domain/IP separation — cannot identify whether a reputation issue originates from the domain's DMARC/content history or from a specific IP's behavior" or "No reputation tracking at all — no historical signal to guide sending decisions"
Remediation: Store reputation signals indexed by both domain and IP:
// Database schema (Prisma example)
model DomainReputation {
id String @id @default(uuid())
domain String @unique
spamRate Float? // Google Postmaster Tools domain reputation
inboxRate Float? // % landing in inbox (from seed list or Postmaster)
dkimPassRate Float?
spfPassRate Float?
dmarcPassRate Float?
updatedAt DateTime @updatedAt
}
model IpReputation {
id String @id @default(uuid())
ipAddress String @unique
spamRate Float? // Google Postmaster Tools IP reputation
microsoftSndsCategory String? // Green/Yellow/Red
lastChecked DateTime
updatedAt DateTime @updatedAt
}