Skip to main content
POST
Check Campaign
Run the pre-send email check on a saved campaign: the same rules as the email checker in the editor, plus live verification of every link and image. Use it in your own approval flow, or before scheduling a campaign through the API.
This endpoint is read-only. It requires the campaigns:read scope and never sends, schedules, or modifies anything. It uses POST only so personalization input can travel in a request body.

Request

string
required
Campaign ID.
string
Check as this stored subscriber: picks their localization and reports merge tags and conditions that would not resolve for them. Link and content rules always run on the email as written. Use this or subscriber, not both. Requires the subscribers:read scope as well.
object
Check as an ad-hoc contact that does not need to exist in your account. Accepts email (required), firstName, lastName, customAttributes, and tags. Use this or subscriberId, not both.
object
Extra merge variables layered over the contact’s attributes.
string
Check a specific localization instead of deriving it from the contact.
string
Check a specific A/B test variant of this campaign.
Verify every link and image over the network. Pass false for a fast, rules-only check that makes no requests.

What gets checked

Links and images are collected from every version recipients can receive: each A/B variant and each translation. Pass variantId or locale to check only that version. Links and images, live. Every web link and image is requested from our servers (HEAD, then GET when a server refuses HEAD), following up to 8 redirects. Each one comes back with a status: {{company.url}} is resolved from your company website before checking. If no website is set, those links are reported as links.missing-website. Links, without a request. Placeholder links (#, a bare https://), buttons with no link, script links, links missing https:// or relative links, mistyped schemes such as htps://, unencoded spaces, incomplete domains, localhost and private addresses, tunnel and deploy-preview URLs, staging subdomains, placeholder domains such as example.com, http:// links, link shorteners, raw IP addresses, link text that shows a different domain than the link goes to, invalid mailto:/tel: links, and unclosed merge tags in URLs. Images. Broken or non-image URLs, images over 1 MB, embedded base64 images, local file paths, placeholder image services, and missing alt text. Content. Leftover placeholder copy (lorem ipsum, [First Name], TODO), name merge tags without a fallback, spam-trigger wording, excessive capitals, profanity, too many or no links, a missing unsubscribe link in marketing email, empty conditional branches, and broken merge tag syntax. Subject and preview text. Length, placeholder text, a fake Re: or Fwd: prefix, spam-trigger wording, capitals, punctuation, emoji, and preview text that repeats the subject. Rendered HTML. Gmail clipping risk, button contrast and tap-target size, and features specific email clients drop. Sender settings (From and Reply-To) are not part of this check.

Response

boolean
true when the check ran.
integer
0 to 100 across subject (25%), preview text (15%) and content (40%), rescaled to 100 because sender settings aren’t part of this check. The editor also weighs your sender (20%), so its score can differ slightly for the same email.
string
A, B, C, D or F.
string
Predicted inbox tab: Primary, Promotions or Spam.
object
subject, preview and content, each with score and maxScore.
object[]
Findings, errors first. Each has category, severity (error to fix before sending, warning to review, info for tips) and message, plus a stable rule ID such as links.broken or content.placeholder-text. When the finding has one location, blockId names the block to edit and url the link or image concerned.
Every link and image: url, kind (link or image), label, blockId, blockType, status, httpStatus, finalUrl (after redirects), message, and findings from the rules that need no request.
Counts: total, checked, ok, broken (broken and invalid), warnings (server_error and unreachable), restricted and notChecked (personalized and not_checked).
false when you passed links: false.
string
Subject line with merge tags resolved for the checked contact.
string | null
Preview text with merge tags resolved, or null when unset.
string
Localization the check used.
object[]
Merge tags that did not resolve, as on the render endpoint.
object[]
Block conditions this check could not decide, as on the render endpoint.
object
What was checked: type, id and variantId.
Results for the same URL are cached for up to 10 minutes (1 minute for failures), so repeating a check right after fixing a broken link can briefly return the old answer. Live checks are limited to 30 calls a minute per API key and company, and 60 a minute per API key across companies; past that you get 429, and links: false still works.