Skip to content
Claim your free business email
Deliverability

Google Postmaster Tools, explained: every dashboard and what to do

By Rasket TeamLast updated 15 min read

Written for email marketers, deliverability specialists and IT admins

The short answer

Google Postmaster Tools is a free Google dashboard showing how Gmail handles the email your domain sends to personal Gmail addresses, not company Google Workspace accounts. Once you prove you own the domain, it shows day by day whether you meet Gmail’s rules, how often readers mark you as spam, and why mail was refused.

What Google Postmaster Tools is

Google Postmaster Tools is Gmail’s own report on your sending domain. It shows what Gmail measured about your mail, such as how many readers marked it as spam and whether it authenticated, rather than what your sending logs recorded.[1]

Use it when your logs and your sales disagree: every message to a Gmail address is logged as delivered, yet a campaign that used to bring 40 orders from Gmail readers now brings 15. Postmaster Tools tells you, about a day later, whether Gmail users are reporting you or your authentication is failing. Gmail doesn’t require it.

Three limits decide whether it will help you:

  • Personal Gmail only. “Data in Postmaster Tools only applies to messages sent to personal Gmail accounts”, meaning addresses ending in @gmail.com or @googlemail.com. Mail to businesses on Google Workspace is not in it, which for a B2B sender can be most of the list; for those recipients, your own bounce and complaint data is the signal (see below).[2]
  • Daily, not live. “Typically, the data is updated within 24 hours but can take longer”, days are counted in UTC, and you can look back up to 120 days.[1]
  • A volume floor. Google’s API guide states the minimum: “Only domains that send mail to at least 50 users per day receive statistics.”[3] That is a floor, not a promise: on any low-volume day, dashboards “might not include all data”, so expect gaps until you are well above it.[1]

Under 50 Gmail addresses a day? Set it up anyway (ten minutes), then skip to what to watch when the charts are empty: your bounces, complaints and replies. The wider picture is in our deliverability guide.

How to set up Google Postmaster Tools

For most senders, the domain to add is simply the one in your From address, such as example.com; on Rasket, it is the domain you verified with us. Google’s exact wording is the domain your mail is authenticated with: the DKIM signing domain (the domain that signs each message, which proves it came from you) or the SPF Return-Path domain (where bounces go). On Rasket, both are your domain or a subdomain of it. [2] If a store or newsletter platform sends for you, check the DKIM line in a message’s headers (see reading headers in Gmail); if it names the platform’s domain, turn on the platform’s custom-domain signing first.

  1. Add the domain. Sign in at postmaster.google.com with any Google account and click Add new domain.[2]
  2. Prove you own it. Choose Verify domain and copy the TXT or CNAME record Google shows. Add it where you manage your domain’s DNS (often the registrar you bought it from), then click Verify. It usually works at once but “can take up to 10 minutes”, and no data appears until it does.[2] A TXT record goes on the domain itself (host @) and is not a second SPF record: only a TXT starting v=spf1 is SPF. [23] Our advice is to keep it published after you verify; Google doesn’t say whether removing it affects access.
  3. Add each subdomain you send from. Once the main domain is verified, its subdomains need no record of their own, and each gets its own dashboards.[2]
  4. Give your team access. Under Manage users, add colleagues by their Google address. Google does not notify them, so tell them yourself.[2]

The Postmaster Tools dashboards, one by one

What each dashboard shows, from Google’s dashboards reference
DashboardWhat it showsWhat good looks like
Compliance statusWhether you meet each Gmail sender requirementCompliant on every line
Spam rateShare of inbox-delivered mail that readers marked as spamSee the next section
Feedback loopSpam rate per campaign, by a Feedback-ID headerNo identifier stands out
AuthenticationSPF, DKIM and DMARC pass ratesGoogle: 95%+ is typical for DKIM and DMARC
EncryptionShare of mail sent to Gmail over TLS100% of your mail to Gmail
Delivery errorsRejected and temporarily failed mail, with reasonsNo new reason, no spike
IP and Domain reputationA Bad-to-High ratingHigh, where still shown

Compliance status

Open this one first. It checks Gmail’s requirements for every sender (SPF or DKIM, DNS records, message formatting, encryption, user-reported spam rate) and three more for bulk senders: DMARC, one-click unsubscribe and honouring unsubscribes. You are a bulk sender once you send “close to 5,000 messages or more to personal Gmail accounts” in 24 hours, counting every subdomain, and you stay one permanently; bulk senders need both SPF and DKIM. [5] [7] Each line reads Compliant, Needs work or No data found.[1]

Three things confuse people. The status is shown for the main domain only, though mail from its subdomains feeds it. It is a rolling average over several days, so after a fix Google says to check again after 7 days. And “Honor unsubscribe” turns to Needs work when requests aren’t processed within 48 hours, even if a firewall or proxy in front of your servers dropped them: Google counts the request anyway.[1]

Feedback loop

A Feedback-ID is a label your sending system writes into each message to say which campaign it belongs to; this dashboard reports the labels whose spam rate is unusual, not every label. The header holds up to three labels you choose (a campaign, a customer, a type of mail) plus a fixed sender ID of 5 to 15 characters, separated by colons and covered by a DKIM signature from a domain you verified in Postmaster Tools. A label appears only on days with enough mail and enough separate spam reports.[6]

A Feedback-ID header, in Google’s format
Feedback-ID: spring-sale:newsletter:marketing:examplecorp

On Rasket this dashboard can’t split your campaigns: there is no way to set a Feedback-ID with your own labels, because the API refuses the header, as it does other headers it manages itself. [20] We have no date for a customer Feedback-ID. Two things cover most of the gap:

  • Complaints per campaign, mostly from other providers. Each campaign’s report counts the recipients who marked it as spam, and GET /broadcasts/{id}/recipients?type=complained lists them. [24] Gmail’s feedback loop gives aggregate rates in Postmaster Tools, not individual complaints, [6] so these come from providers that report each one, such as Yahoo.
  • Gmail’s rate for campaigns alone. Send marketing from its own subdomain (the rule of thumb is in marketing email on a subdomain) verified in Rasket as a domain of its own, so its mail is signed with the subdomain. Add it to Postmaster Tools and its Spam rate dashboard counts campaigns only.[2]

If you need Gmail’s own per-campaign numbers, use a provider that sets a Feedback-ID with your labels, covered by your domain’s DKIM signature.

Authentication

The share of mail with your domain in the From header that passes SPF, DKIM and DMARC. Google’s benchmark: senders “typically achieve 95% or higher success rates for DKIM and DMARC when these methods are set up correctly.”[1] If DMARC passes less often than DKIM, suspect alignment: the mail authenticates, but as some other domain than the one in From.

Our rule of thumb for DKIM and DMARC (not SPF, which forwarding pulls down on its own): forwarding costs a few points, so 85% to 95% points to a tool that sends as your domain isn’t aligned with it. Without DMARC reports, send yourself one message from each tool that mails as you and, in Gmail’s Show original, check that the d= in its DKIM-Signature line or its Return-Path is your domain or a subdomain of it (how to read headers); a tool with neither is the one to fix. Below 85%, start with whatever changed in your DNS that week.

Encryption

The share of your mail that reached Gmail over TLS, which Gmail requires from every sender.[7] A few points under 100% usually means forwarding servers without TLS; a reading of 0% points to an invalid or expired certificate or an outdated TLS version.[1]

IP and Domain reputation: being retired

Every old dashboard carries over to the new Postmaster Tools (v2) “with the exception of the Domain and IP Reputation dashboards, which will be retired”, because reputation “is only one of many factors affecting deliverability”. The v2 API has dropped them already.[4] At 17 October 2026 Google gives no date for the interface, and its reference still describes the four ratings (Bad, Low, Medium, High). [1] So check your own account. If the charts are missing, they have been retired for you and nothing is wrong with your domain. If they are still there, read them as a slow, lagging summary, not a target.

For an earlier warning, watch the temporary failures in Delivery errors.

Reading the spam rate correctly

Google defines it as “the percent of your messages that are delivered to engaged recipient’s Inbox and then marked as spam by the recipient”, counted on DKIM-authenticated mail.[1]

The spam rate divides the messages people mark as spam by the messages delivered to engaged recipients’ inboxes; mail Gmail filtered to spam is left out.Your mail to GmailDKIM-authenticatedDelivered to the inboxof engaged recipientsFiltered to spam by Gmailnot in the spam rateMarked as spamby the recipientSpam rate =marked as spamdelivered to the inbox
The Spam rate dashboard, drawn from Google’s definition.

0.1%

is the rate to stay below, and 0.3% the one never to reach; what each costs you is in our spam complaint rate guide. On a small list one complaint moves it a long way: at 500 inbox deliveries, one is 0.2%.
Source: Gmail Help, Google, “Email sender guidelines” [7]

So read the spam rate beside a number Gmail can’t inflate for you: orders or replies from addresses ending @gmail.com (clicks too, though security scanners add some). If the rate falls while those fall too, treat it as a warning and work through why emails go to spam.

Delivery errors and what to do about each

The Delivery errors dashboard shows the share of authenticated mail Gmail rejected or temporarily failed, with a reason for each.[1]

Delivery error reasons from Google’s dashboards reference, and what to do
ErrorWhat Gmail is sayingWhat to do
Rate limit exceededYou are sending at a suspiciously high rateStop, resume in a few minutes, then send at a constant rate
Suspected spamUsually low domain or IP reputationFind the mail drawing complaints; escalate if it persists
Content possibly spammySomething in the message, such as links, looks like spamReview content and links
Bad attachmentAn unsupported file typeSend only supported attachments
DMARC policyMail failed DMARC on a domain with p=rejectFind the failing sender in your DMARC reports; Google’s stopgap, p=none, also ends spoofing protection
Low IP or domain reputationGmail distrusts the sourceFind the stream and list segment drawing complaints; changing IPs won’t repair a domain
Domain or IP on a public blocklist (RBL)Listed by a public blocklist operatorFix the cause first, then ask the list operator for removal
Bad or missing PTRNo reverse DNS for the IPAsk whoever owns the IP (usually your provider) for a PTR that resolves back to it

Temporary failures are Gmail’s throttle. Google’s advice is to “completely stop sending for a short period of time, then resume sending at a slower rate”; otherwise permanent failures tend to follow. [1] Your own deferral count shows it the same day: 60 of 4,000 Gmail messages deferred last week and 400 this week, at the same volume, is throttling (our example figures). Pacing a new domain is covered in how to warm up a new domain or IP address.

If a problem persists after you meet Google’s guidelines, the domain’s verified owner can escalate it from Postmaster Tools with Report delivery issue, at the bottom left. The message you report must be DKIM and SPF authenticated, with a From domain matching the domain.[8]

A ten-minute weekly routine

Keep one row per week in a sheet; with two minutes, do the first two steps.

  1. Compliance status: anything not Compliant?

    Open the tooltip on any line marked Needs work, fix what it names, and note the date. Check that line again 7 days later, because the dashboard is a rolling average.

  2. Spam rate: write down the week's worst day

    Record the highest daily rate, not the average, and the week's orders or clicks from addresses ending @gmail.com, in one row of a sheet like the example below.

  3. Authentication and encryption: compare with last week

    A drop in the DKIM or DMARC pass rate usually follows a DNS change or a new tool sending as your domain. Find what changed that week before anything else.

  4. Delivery errors: look for a new reason

    A reason you have not seen before matters more than the level. Match it to the action in the delivery errors table, and check your own Gmail deferral count for the same days.

One week’s row in the tracking sheet (our example figures)
Week ofNot CompliantWorst-day spam rateGmail ordersDKIM / DMARCNew error reason
12 Oct 2026None0.06% (Tue)212 (last week 224)99.8% / 99.1%None

That row is also your report upward once the reputation charts are gone: compliance, the worst day against 0.1%, and whether Gmail readers still act.

When the charts are empty, and what Gmail’s data misses

Below the volume floor, or for any mailbox provider other than Gmail, use these instead:

  • Your own delivery data. Watch bounce and complaint rates, plus replies. On Rasket, the Metrics page and API give them by date range and domain, [21] and delivery events arrive as webhooks, including email.delivery_delayed for a deferral. [22]
  • A seed test. Sending one message to a set of test inboxes shows where it landed that day. It is a spot check, not a measurement; how to run one for free is in our spam troubleshooting guide.
  • Outlook.com: Microsoft’s Smart Network Data Services (SNDS) gives whoever owns an IP range daily data per address. On a shared pool the IPs belong to your provider, so this one is theirs to watch.[17]
  • Yahoo and AOL: Yahoo’s Complaint Feedback Loop sends you copies of spam complaints for your DKIM-signing domain.[18]

No aggregate data, Postmaster Tools included, shows Primary versus Promotions (a seed test shows only where your seed inboxes put it); see getting out of the Gmail Promotions tab. If you don’t write code, you can stop reading here.

For developers: the Postmaster Tools API

To chart Gmail’s numbers beside your own, or alert on them, use the Postmaster Tools API. Setup is a Google Cloud project with the API turned on, an OAuth client, and a user with access to the verified domain.[9] Request https://www.googleapis.com/auth/postmaster.traffic.readonly, the narrowest scope that reads statistics, not the quickstart’s postmaster, which “allows read/write access”. [11] [10]

Statistics come from domains.domainStats.query, a POST whose body names the metrics you want (SPAM_RATE, AUTH_SUCCESS_RATE, TLS_ENCRYPTION_RATE, DELIVERY_ERROR_RATE and others) and a time range.[12] The sample follows the REST reference, not the startDate and endDate in Google’s quickstart and migration guide, which the reference doesn’t define. [16] It reads the last seven complete days, every page, and stores its token so cron can run it:

Python: Postmaster Tools API v2, one week of spam and DKIM rates, with a spam-rate alert
# pip install google-api-python-client google-auth-oauthlib
import datetime
import os
import sys

from google.auth.exceptions import RefreshError
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# Read-only access to traffic statistics: the narrowest scope that can query them.
SCOPES = ["https://www.googleapis.com/auth/postmaster.traffic.readonly"]
HERE = os.path.dirname(os.path.abspath(__file__))  # cron runs from another directory
TOKEN_FILE = os.path.join(HERE, "token.json")


def load_credentials():
    creds = None
    if os.path.exists(TOKEN_FILE):
        creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
    if creds and creds.valid:
        return creds
    if creds and creds.expired and creds.refresh_token:
        try:
            creds.refresh(Request())
        except RefreshError:
            # Revoked, or a "Testing" app's 7-day token expired: consent again by hand.
            raise SystemExit("Refresh token rejected: delete token.json and run once by hand.")
    elif not sys.stdin.isatty():
        raise SystemExit("No valid token.json: run once by hand to consent.")
    else:
        # First run only, by hand: opens a browser for consent. credentials.json is a
        # Desktop-app OAuth client from your Google Cloud project.
        flow = InstalledAppFlow.from_client_secrets_file(os.path.join(HERE, "credentials.json"), SCOPES)
        creds = flow.run_local_server(port=0)
    # The refresh token is a long-lived secret: owner-only, and never in the repo.
    with os.fdopen(os.open(TOKEN_FILE, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600), "w") as f:
        f.write(creds.to_json())
    os.chmod(TOKEN_FILE, 0o600)  # also tightens a token.json that already existed
    return creds


service = build("gmailpostmastertools", "v2", credentials=load_credentials())

# The last 7 complete UTC days, ending 2 days ago because data lands about a day late.
end = datetime.datetime.now(datetime.timezone.utc).date() - datetime.timedelta(days=2)
start = end - datetime.timedelta(days=6)


def as_date(d):
    return {"year": d.year, "month": d.month, "day": d.day}


body = {
    "metricDefinitions": [
        {"name": "spam_rate", "baseMetric": {"standardMetric": "SPAM_RATE"}},
        {
            "name": "dkim_pass_rate",
            "baseMetric": {"standardMetric": "AUTH_SUCCESS_RATE"},
            "filter": 'auth_type = "dkim"',
        },
    ],
    "timeQuery": {
        "dateRanges": {
            "dateRanges": [
                {"start": as_date(start), "end": as_date(end)}
            ]
        }
    },
    "pageSize": 200,  # the default is 10: one week of two metrics is 14 rows
}

stats = []
while True:
    try:
        response = (
            service.domains()
            .domainStats()
            .query(parent="domains/example.com", body=body)
            .execute(num_retries=5)  # retries 429s and 5xx errors with exponential backoff
        )
    except HttpError as err:
        # 403 PERMISSION_DENIED: this account can't see the domain in Postmaster Tools.
        raise SystemExit(f"Postmaster Tools query failed: {err}")
    stats.extend(response.get("domainStats", []))
    token = response.get("nextPageToken")
    if not token:
        break
    body["pageToken"] = token

if not stats:
    # Google returns rows only for dates where it has data: below the volume floor, or after
    # lost access, this is empty. Exit 1 so a silent week isn't read as a good one.
    sys.exit("No data for this range.")

# v2 doesn't document the unit. Compare one day with the dashboard, then set this: True if the
# raw value is the dashboard's percentage (0.06 for 0.06%), False if a ratio (0.0006).
SPAM_RATE_IS_PERCENT = None
WARN_AT = 0.001  # 0.1%: Google's recommended ceiling
INCIDENT_AT = 0.003  # 0.3%: the level never to reach

# Each row is one metric on one day: {"metric", "date", "value": {"doubleValue": ...}}

alerts = 0
for stat in stats:
    d = stat.get("date") or {}
    day = f'{d.get("year", 0)}-{d.get("month", 0):02}-{d.get("day", 0):02}'
    v = stat.get("value", {})  # a StatisticValue: doubleValue, floatValue or intValue
    value = float(next((v[k] for k in ("doubleValue", "floatValue", "intValue") if k in v), 0))
    if stat["metric"] == "spam_rate" and SPAM_RATE_IS_PERCENT is not None:
        rate = value / 100 if SPAM_RATE_IS_PERCENT else value
        level = "INCIDENT" if rate >= INCIDENT_AT else "WARN" if rate > WARN_AT else "ok"
        print(f"{day} spam rate {rate:.3%} {level} (raw {value})")
        alerts += level != "ok"
    else:
        print(f"{day} {stat['metric']} {value}")

# A non-zero exit is what cron, CI or a monitoring wrapper notices.
if SPAM_RATE_IS_PERCENT is None:
    sys.exit("Set SPAM_RATE_IS_PERCENT to turn alerts on.")  # exit 1 until calibrated
sys.exit(1 if alerts else 0)
  • Unattended runs need a stored user token. “All requests to the Postmaster Tools API must be authorized by an authenticated user”, and Google documents no service-account route, so consent once, as above. [10] Use a role account added under Manage users, not a person. An External consent screen still in “Testing” issues refresh tokens that expire in 7 days; publish the app, or use an Internal screen in Google Workspace.[19]
  • Some metrics need a filter. AUTH_SUCCESS_RATE wants auth_type set to spf, dkim or dmarc; TLS_ENCRYPTION_RATE wants traffic_direction. DELIVERY_ERROR_RATE takes error_type and error_reason, to chart each reason per day. Results default to 10 rows a page, 200 at most, and come back only for dates where Google has data. [12]
  • Check the units once, then alert. v2 calls SPAM_RATE a “predefined metric for spam rate” and returns a doubleValue with no unit; [13] [14] v1 defined it as a ratio. [15] We can’t show you a live value, so compare one day with the dashboard and set SPAM_RATE_IS_PERCENT. Until then the sample prints raw values and exits 1 with a reminder; after, it flags days above 0.1%, calls 0.3% an incident and exits 1 so cron notices.[7]

The API only answers queries, and the numbers change once a day, so poll daily. domains.getComplianceStatus returns Compliance status, and v1 code needs moving: Google says v1 “will be retired”.[4]

Frequently asked questions

What does “No data found” mean in the Compliance status dashboard?

Gmail did not receive enough mail matching that requirement's filter to judge it. For DNS-based lines, the status reflects the records Gmail saw when your mail arrived, not your current configuration, so Google suggests checking live DNS with its Admin Toolbox Check MX tool.

Does mail a recipient rescues from the spam folder count in the spam rate?

Yes. Google counts messages that went to spam and were then marked as not spam by the recipient as delivered to the inbox. They join the base of the calculation, so rescued mail lowers your rate a little rather than being ignored.

Are forwarded messages included in Postmaster Tools data?

Google tries to exclude forwarded mail but says some dashboards may still include it. Forwarding also explains other oddities: authentication and TLS rates below what you expect, and delivery error rates higher than your own logs, because the forwarding server receives those errors.

Can an agency or a second team see the same domain in Postmaster Tools?

Yes, in two ways. A verified owner can add them under Manage users, as long as they have a Google account. Or each account can verify the domain itself: Google says to publish a separate DNS verification record for every account that needs access.

My DNS host only lets me add CNAME records. Can I still verify?

Yes. Google's verification window offers either a TXT or a CNAME record, and either proves ownership. If verification fails, Google's own checklist is to wait a few minutes, check the string was copied exactly, and try again with a new one.

Are there quotas or token limits on the Postmaster Tools API?

Google's Postmaster pages publish no quota table, so check the API's Quotas page in your Cloud project. One documented limit bites collectors: 100 refresh tokens per Google account per OAuth client, after which a new token silently invalidates the oldest one.

Sources

24 primary sources, each read on the date shown.

See all sources
  1. 1.Postmaster Tools dashboards — Gmail Help, Google,
  2. 2.Set up Postmaster Tools — Gmail Help, Google,
  3. 3.Retrieve email statistics — Google for Developers,
  4. 4.Learn about the deprecation of the old Postmaster Tools interface — Gmail Help, Google,
  5. 5.Email sender guidelines FAQ — Gmail Help, Google,
  6. 6.Feedback Loop — Gmail Help, Google,
  7. 7.Email sender guidelines — Gmail Help, Google,
  8. 8.Report delivery issues in Postmaster Tools — Gmail Help, Google,
  9. 9.Postmaster Tools API overview — Google for Developers,
  10. 10.Set up the API (OAuth 2.0 scopes) — Google for Developers,
  11. 11.Python quickstart — Google for Developers,
  12. 12.Method: domains.domainStats.query (v2 REST reference) — Google for Developers,
  13. 13.MetricDefinition (v2 REST reference) — Google for Developers,
  14. 14.QueryDomainStatsResponse (v2 REST reference) — Google for Developers,
  15. 15.REST Resource: domains.trafficStats (v1 reference) — Google for Developers,
  16. 16.Migrate to Postmaster Tools API v2 — Google for Developers,
  17. 17.SNDS – Frequently Asked Questions — Outlook.com Smart Network Data Services, Microsoft,
  18. 18.Sender Requirements & Recommendations — Yahoo Sender Hub,
  19. 19.Using OAuth 2.0 to Access Google APIs (refresh token expiration) — Google for Developers,
  20. 20.Emails API reference (custom headers) — Rasket docs,
  21. 21.Metrics API reference — Rasket docs,
  22. 22.Events — Rasket docs,
  23. 23.RFC 7208: Sender Policy Framework (SPF), §4.5 Selecting Records — IETF,
  24. 24.Broadcasts API reference (list a broadcast's recipients) — Rasket docs,

Keep reading

Written by the Rasket Team. First published ; last checked against its sources . See something out of date? How we correct guides.

Send email that earns its place

Authenticated mail, one-click unsubscribe, and campaigns measured apart from your transactional mail, set up in minutes.