API Reference

Deliverability check

Ask "is this ready?" before you send. The deliverability check scores email content against fixed rules — the same rules behind the deliverability score in the campaign editor — and returns a verdict, the issues found, and what each one costs. The same email always gets the same score. It is a pure pre-send check: nothing is sent and no email is logged.

Overview

MethodPathDescription
POST/api/v1/deliverability/checkScore email content; returns a verdict. Does not send.

Requires a key with the deliverability:check scope (a full-access key has it). Checks are unmetered, and this endpoint has its own limit of 20 requests per minute, separate from the 1,000/minute your other calls share.

Why check before sending

Anyone can generate an email. Whether it reaches the inbox depends on what filters actually weigh: where the links go, the balance of text and images, honest personalisation and a clean subject — plus your sender reputation, which no content check can see. Run the check in your send pipeline and branch on the verdict: hold on DANGER, surface issues for a human or an agent to improve, then send. Each issue carries a stable rule and code so you can decide programmatically.

The check reads the content you send and never opens the links or pictures in it, so it cannot tell you whether an address answers. In the app, the review page and the approval screen open them, and the editor does when you press Check links: those screens can add a link that doesn't open or a picture that doesn't load to the same score. This endpoint never does, so the same content can score higher here than on the review page.

The verdict object

FieldTypeDescription
scorenumber0–100, higher is better. Always 100 minus the points of the issues listed, never below 0, so it is explained by them.
verdictstringDANGER when something is unfinished (don't send it as is), GOOD at 90 or above, otherwise WARNING.
summarystringA short summary, such as "2 things to improve" or "Looks good".
issuesIssue[]What would make the email better, most important first (see below). Empty when there is nothing to improve.
suggestionsstring[]The suggestions of the first three issues, for a quick summary.

Issue

FieldTypeDescription
codestringStable category an agent can branch on: subject, content, structure, or spam.
severitystringhigh means unfinished — the campaign editor holds a send until it is resolved. medium costs 10 points or more, low less.
titlestringWhat was noticed, in a sentence.
descriptionstringWhy it matters.
fixstringWhat would be better.
rulestringThe rule that raised it — a stable identifier, such as link_shortener, for branching on one finding.
pointsnumberWhat this issue costs. The score is 100 minus the sum, never below 0.

Check deliverability

POST/api/v1/deliverability/check

Send a subject and the body as html and/or text. Returns 200 with the verdict. Nothing is sent and no email log row is written.

Request body

FieldTypeRequiredDescription
subjectstringrequiredThe subject line to score.
htmlstringoptionalHTML body to analyze. Provide this and/or text (HTML is preferred).
textstringoptionalPlaintext body. Used when html is omitted. At least one of html/text is required.

Response

"color:#ff7b72">import { PristineSend } "color:#ff7b72">from "pristinesend"

"color:#ff7b72">const ps = "color:#ff7b72">new PristineSend(process.env.PRISTINESEND_API_KEY!)

// A pre-send check — nothing is sent. Decide send / improve / hold "color:#ff7b72">from the verdict.
"color:#ff7b72">const v = "color:#ff7b72">await ps.deliverability.check({
  subject: "Your June invoice is ready",
  html: "color:#a5d6ff">'<p>Hi {{ first_name }} — your invoice for June is ready.</p><p><a href="https://bit.ly/june-invoice">View your invoice</a></p>',
})

console.log(v.score, v.verdict) // 82 "WARNING"
if (v.verdict === "DANGER") {
  // Something is unfinished (a placeholder link, an empty image spot). Don't send it "color:#ff7b72">as is.
  throw "color:#ff7b72">new Error(v.issues.filter((i) => i.severity === "high").map((i) => i.title).join(" "))
}
for ("color:#ff7b72">const issue of v.issues) {
  console.log(`-${issue.points} ${issue.title} ${issue.fix}`)
}

Errors

All errors use the standard envelope. The codes specific to this endpoint:

StatuscodeWhen
400missing_fieldNo subject, or neither html nor text supplied.
400invalid_fieldsubject/html/text present but not a string.
401unauthorizedMissing or invalid API key.
403insufficient_scopeThe key lacks the deliverability:check scope.
429rate_limitedPer-key rate limit exceeded.
503rate_limit_unavailableThe rate limit could not be checked, so the request was refused — retry.

See the full Error codes reference for the canonical envelope and the complete list.