The measuring instrument for email addresses at signup and checkout.
Version 1.0 · 2026-09-15
Story
rate.email scores an email address before it becomes a customer, and returns one of three verdicts: accept, review or reject. Every verdict carries reason codes, so a merchant can see exactly what the score is made of. The brand behaves like a calibrated instrument: it reports a reading, states its confidence, and leaves the decision to the shop.
What the brand is not: an alarm, a shield, a firewall. No sirens, no padlocks, no threat language. The tone is the tone of a bench instrument manual.
Logo
The mark is a dial: a ring that opens at the bottom, three graduations, a needle resting in the upper range, and a tail that carries the ring out into an "at" sign. It reads as measurement first and as email second, which is the order the product works in.
logo.svg on white and on surfaces lighter than #E4E7ED.
logo-dark.svg on surfaces darker than #38424F. The product itself is light only; keep this file for a partner's dark footer, a slide, or any third-party surface that is dark.
Clear space and minimum size
Clear space on all sides equals the height of the dial mark. Nothing crosses it: no text, no rules, no image edges.
Minimum sizes: full logo 96px wide on screen, 24mm in print. Logomark 20px. Below 20px use favicon.svg, which drops the fine graduations.
Do and do not
Do. Keep the needle at its drawn angle. It always points into the accept range.
Do not. Rotate, skew or mirror the mark. A tilted dial is a broken dial.
Do not. Place the logo on gradients, photos or verdict colours.
Do not. Stretch, recolour the needle, or add effects, outlines or shadows.
Colour
One accent, a cool graphite neutral ramp, and three verdict hues. The verdict hues are blue shifted on purpose, so red and green confusion does not collapse accept into reject. Colour never carries a verdict alone: an icon and a word always travel with it.
Ultramarine ink, the accent
50100200300400500600700800900
Graphite, the neutral ramp
02550100200300400500600700800900950
Contrast
All pairs below are measured against WCAG 2.1. Every pair passes AA for normal text at 4.5:1. Pairs marked AAA pass 7:1.
Role
Foreground
Background
Ratio
Level
Heading text
#10151C
#F7F8FA
17.24
AAA
Body text
#38424F
#F7F8FA
9.59
AAA
Muted text
#5A6675
#F7F8FA
5.50
AA
Link, accent text
#2B3FAE
#F7F8FA
8.15
AAA
Text on accent
#F7F8FA
#2B3FAE
8.15
AAA
Accept text
#0E7255
#E2F4EC
5.17
AA
Review text
#8A5300
#FBEEDA
5.53
AA
Reject text
#BC1B45
#FCE7EC
5.26
AA
White on accept fill
#FFFFFF
#0E7255
5.90
AA
Ink on review fill
#10151C
#F2B851
10.25
AAA
White on reject fill
#FFFFFF
#BC1B45
6.21
AA
Typography
IBM Plex Sans for everything a person reads, IBM Plex Mono for everything a machine produced: scores, reason codes, API payloads, keys, timings. The two faces share skeletons, so a score sitting inside a sentence does not look pasted in. Both are licensed under the SIL Open Font License 1.1.
Weights in use: 400 payloads, 500 numerals in dense UI. Tabular figures on. Stack: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace
Scale
4xl / 2.488rem / 600
Page title
3xl / 2.074rem / 600
Section opener
2xl / 1.728rem / 600
Section heading
xl / 1.44rem / 600
Subheading
lg / 1.2rem / 400
Lede paragraph
md / 1rem / 400
Body copy, the default
sm / 0.917rem / 400
Dense tables and admin grids
xs / 0.833rem / 400
Chips, hints, captions
2xs / 0.694rem / 500
Numeric labels on gauges only
Body line length stays under 68 characters. Line height 1.6 for body, 1.15 for headings. Headings track in at -0.02em. Never set a label in all caps: the product already uses upper case for reason codes, and that distinction has to stay readable.
Verdict badges
Three verdicts, three shapes: a check, a clock, a crossed circle. The shape does the work when colour cannot, which covers colour blindness, grayscale print and the dense Magento grid. The label is always spelled out unless the column is narrower than 90px. The verdict comes from the severities present in the reasons, not from the score, so the badge and the gauge answer two different questions and are never presented as one.
AcceptReviewReject
AcceptReviewReject
Soft badges are the default. Solid fills are for one place only: the single primary verdict at the top of a detail view. Two solid badges must never appear in the same view.
Verdict
Rule
Icon
What the merchant does
Accept
No medium or high reason
check
Let the order through.
Review
Any medium reason, no high
clock
Hold and look at the reason codes.
Reject
Any high reason
crossed circle
Block the signup, ask for another address.
Score gauge
The gauge is the one place where the brand raises its voice. It is the logo mark opened out to full size: the same graduations, the scale widened to 240 degrees so five marks fit, and the needle flattened into a cursor that rides the arc, which leaves the centre to the numeral. The cursor moves once, when the reading arrives, and holds. Reduced motion turns the movement off and the cursor simply appears at the reading.
Accept
No medium or high reason. One low reason, NO_DMARC.
Review
Two medium reasons: ROLE_ACCOUNT and CATCH_ALL.
Rules: the numeral is mono and tabular, the track keeps its full 240 degrees at every score, the arc colour follows the verdict and not the number, and the gauge is never used for anything that is not a 0 to 100 score. The score starts at 100 and every reason subtracts from it, so a low score explains a verdict but never sets it.
Reason code chips
Reason codes are printed exactly as the API returns them, in mono upper case. A chip carries a severity dot on the left, matching the four levels the API uses. High and medium decide the verdict. Low trims the score. Info is context and changes nothing. The info dot is hollow rather than a fourth grey, so the four levels stay apart in print and for colour blind readers, and the severity word is always in the tooltip.
Never translate a reason code in the UI. Put the plain language sentence next to it, or under it, and keep the code itself searchable. Maximum four chips in a grid cell, then a count: +3
API response
Payload samples are always shown on the code surface, a dark inset block, so a code block reads as machine output rather than page content. The sample follows the response contract in spec/openapi.yaml, field for field, because a brand book that drifts from the API teaches the wrong shape.
{"email":"J.Kowalski+shop@Mailinator.com","normalized":"j.kowalski@mailinator.com","local_part":"j.kowalski","domain":"mailinator.com","verdict":"reject","score":35,"reasons":[{"code":"DISPOSABLE_DOMAIN","severity":"high","source":"allowlist:disposable","message":"mailinator.com is a known disposable email domain."},{"code":"SUBADDRESS","severity":"info","source":"syntax","message":"Plus-addressing detected; normalized form removes the tag."}],"checks":{"syntax":{ "valid":true, "rfc5322":true, "suggestion":null },"domain":{ "resolves":true, "mx":["mailinator.com"], "spf":true, "dmarc":"none", "age_days":null },"provider":{ "type":"disposable", "name":"Mailinator" },"deliverability":{ "status":"skipped", "provider":null, "checked_at":null }},"cache":{ "hit":false, "age_seconds":0, "ttl_seconds":21600 },"meta":{ "request_id":"01J8Z3F1QK9X7N2M5T6R8W0V4B", "latency_ms":38, "version":"2026-09-15" }}
Syntax colours: keys ultramarine 300, strings accept 300, numbers review 300, literals reject 300, punctuation muted. Four hues, same family as the rest of the system, no rainbow theme.
Buttons and inputs
Buttons
One primary action per view. Labels name the action, and the result keeps the same word: "Run a check" produces "Check complete". No arrows appended to labels. Corner radius 3px on every control, because the system reads as a panel, not as cards.
Inputs
Checked against MX, disposable lists and typo patterns.
Key rejected. Copy the key again from the dashboard.
Inputs that hold machine values are set in mono. Focus is a 1px accent border plus a 3px accent ring, never a colour change alone.
Iconography
Icons are drawn on a 24 grid with a 2.2px stroke, round caps, round joins and no fill except the needle pivot. Every icon is built from the dial vocabulary: circle, arc, tick, needle. Nothing in the set may be a shield, a padlock, a siren or a warning triangle, and the envelope appears only when the subject really is a message and not an address.
acceptreviewrejectscoredomainapi key
Icons take the colour of the text they sit with. A verdict icon is never shown without its label or an accessible name.
Voice and tone
Report the reading, name the next step, stop. The product talks about addresses and domains, never about people. Words like fraudster, attacker, threat and protection stay out, because the API does not know intent, it knows signals.
Do
State the measurement. Give the number before the adjective. Use sentence case. Say what the merchant can do next. Name a verdict by its exact word: accept, review, reject.
Do not
No threat language. No exclamation marks. No apologies in errors. No hedging like "may possibly". No marketing adjectives on a score.
Microcopy
empty state, dashboardNo checks yet. Send your first address to POST /v1/rate.
error, invalid keyAPI key rejected. Copy the key again from the dashboard, then save.
error, rate limitRate limit reached at 1000 checks per minute. Retry in 12 seconds.
tooltip, review verdictHeld for review. The domain accepts every address, so delivery cannot be confirmed.
config help, MagentoPick what happens on each verdict. The score explains the verdict, it does not set it.
For the Magento admin
In a Magento grid the verdict gets one column, often under 110px, next to a UI kit the brand does not control. The rules: keep the icon, keep the score, drop the word when the column is narrower than 90px, and never restyle the surrounding grid. Adminhtml owns the table, rate.email owns one cell.
ID
Email
rate.email
Reasons
Created
10241
anna.w@gmail.com
95 Accept
NO_DMARCFREE_PROVIDER
2026-09-15 08:12
10242
office@nowa-firma.pl
65 Review
ROLE_ACCOUNTCATCH_ALL
2026-09-15 08:31
10243
j.kowalski@mailinator.com
35 Reject
DISPOSABLE_DOMAIN+1
2026-09-15 08:44
Narrow column, 88px
95
65
35
The compact cell keeps an accessible name on the icon, for example aria-label="Reject, score 35", so the column is readable by screen reader and in grayscale export. Column filters use the verdict words, not the colours.