PECR Check API reference

Send a UK email address, get deliverability, free webmail screening, the UK registered company behind the domain and a PECR subscriber verdict, with a stored audit record for every check.

Overview

  • Base URL: https://pecrcheck.emailmovers.services/api/v1
  • REST over HTTPS. Request and response bodies are JSON.
  • Authentication: Authorization: Bearer <api_key>
  • Every verify result includes an audit_id for a stored evidence record.

A verdict is a classification with evidence, not legal advice. You remain the sender or instigator and are responsible for your message content, PECR reg 23 (identify yourself and give an opt-out), your legitimate interests assessment and handling objections.

Authentication

Create an API key in your dashboard. Keys look like pc_live_.... Send it in the Authorization header on every request. Keep keys on your server: never put them in browser or mobile app code.

Authorization: Bearer pc_live_...

Verify one address

POST /verify

FieldTypeDescription
emailstring, requiredThe address to check.
min_confidencenumber, optional0 to 1, default 0.85. A corporate match below this is downgraded to UNKNOWN with LOW_CONFIDENCE_MATCH.
referencestring, optionalYour own ID (for example a CRM contact), stored on the audit record.

curl

curl -X POST https://pecrcheck.emailmovers.services/api/v1/verify \
  -H "Authorization: Bearer $PECRCHECK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "jane.smith@acme-widgets.co.uk", "reference": "crm-contact-991" }'

Node (fetch)

const response = await fetch('https://pecrcheck.emailmovers.services/api/v1/verify', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.PECRCHECK_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'jane.smith@acme-widgets.co.uk',
    min_confidence: 0.85,
    reference: 'crm-contact-991',
  }),
});

if (!response.ok) {
  const { error, message } = await response.json();
  throw new Error(`${error}: ${message}`);
}

const result = await response.json();

if (result.recommended_action === 'MAY_SEND_WITH_OPT_OUT') {
  // Corporate subscriber: send, identify yourself and include an opt-out.
} else {
  // Anything else: do not send marketing without consent.
}

Response: corporate subscriber (illustrative data)

{
  "audit_id": "pc_aud_7mQ2xK9vR4tN8bLs",
  "checked_at": "2026-10-22T09:41:07Z",
  "email_hash": "sha256:4b1d...e9",
  "domain": "acme-widgets.co.uk",
  "deliverability": {
    "status": "deliverable",
    "mx_found": true,
    "smtp_check": "accepted",
    "catch_all": false,
    "disposable": false,
    "role_account": false,
    "free_webmail": false
  },
  "company": {
    "name": "ACME WIDGETS LIMITED",
    "company_number": "01234567",
    "company_type": "ltd",
    "status": "active",
    "registered_country": "GB"
  },
  "verdict": "CORPORATE_SUBSCRIBER",
  "recommended_action": "MAY_SEND_WITH_OPT_OUT",
  "confidence": 0.94,
  "reason_codes": ["COMPANY_MATCHED", "COMPANY_ACTIVE"],
  "policy_version": "2026-10-01",
  "notes": "PECR reg 22 consent rule does not apply to corporate subscribers. Identify yourself and include an opt-out (reg 23). UK GDPR applies to named individuals.",
  "billable": true,
  "cached": false
}

Response: free webmail (illustrative data)

{
  "audit_id": "pc_aud_Xw3pZ0fC1d5Eh2Jk",
  "checked_at": "2026-10-22T09:41:08Z",
  "email_hash": "sha256:9c2a...41",
  "domain": "gmail.com",
  "deliverability": {
    "status": "not_checked",
    "mx_found": null,
    "smtp_check": "not_checked",
    "catch_all": null,
    "disposable": false,
    "role_account": false,
    "free_webmail": true
  },
  "company": null,
  "verdict": "INDIVIDUAL_SUBSCRIBER",
  "recommended_action": "CONSENT_REQUIRED",
  "confidence": null,
  "reason_codes": ["FREE_WEBMAIL"],
  "policy_version": "2026-10-01",
  "notes": "Free webmail address: treat as an individual subscriber.",
  "billable": false,
  "cached": false
}

Result fields

FieldDescription
audit_idID of the stored evidence record for this check.
checked_atUTC timestamp of the check (ISO 8601).
email_hashSHA-256 hash of the normalised address. The plaintext is not stored.
domainThe domain part of the address.
deliverability.statusdeliverable, mx_valid, undeliverable, unknown or not_checked.
deliverability.mx_foundWhether the domain has mail servers (null if not checked).
deliverability.smtp_checkMailbox check result: accepted, rejected, catch_all, unknown, timeout or not_checked.
deliverability.catch_allWhether the domain accepts mail for any mailbox (null if unknown).
deliverability.disposableWhether the address is a disposable inbox.
deliverability.role_accountWhether the address is a role account such as info@.
deliverability.free_webmailWhether the address is free webmail or a consumer ISP.
companyThe matched UK company (name, company_number, company_type, status, registered_country), or null.
verdictOne of the verdicts below.
recommended_actionMAY_SEND_WITH_OPT_OUT, REVIEW, CONSENT_REQUIRED or DO_NOT_SEND.
confidenceMatch confidence from 0 to 1, shown only with CORPORATE_SUBSCRIBER; otherwise null.
reason_codesArray of reason codes explaining the verdict.
policy_versionVersion of the verdict rules used, so you can show which rules applied.
notesA short plain English note about the verdict.
billableWhether this check counted against your plan.
cachedWhether this is a cached result from the last 30 days.

Verdicts and recommended actions

verdictMeaningrecommended_action
CORPORATE_SUBSCRIBERThe domain matched an active UK body corporate (a company, LLP, Scottish partnership and so on).MAY_SEND_WITH_OPT_OUT PECR reg 22 consent is not required. Identify yourself and include an opt-out. UK GDPR still applies to named individuals.
PUBLIC_SECTOR_BODYA recognised UK public sector domain, such as gov.uk or nhs.net. Only some government bodies are corporate subscribers.REVIEW Treat as corporate only under your own policy.
INDIVIDUAL_SUBSCRIBERFree webmail or a consumer ISP address.CONSENT_REQUIRED Consent or the soft opt-in is needed. For invites, let the user share their own referral link.
UNKNOWNNo confident UK match, several candidates, a dissolved or inactive company, or a match below your confidence threshold.CONSENT_REQUIRED ICO guidance (the ICO is now the Information Commission) says that if you are unsure, treat the address as an individual subscriber.
UNDELIVERABLEInvalid syntax, no mail servers, a mailbox that does not exist, or a disposable inbox.DO_NOT_SEND Do not send.
SUPPRESSEDThe address or its domain is on your suppression list.DO_NOT_SEND Do not send.

confidence is only returned with CORPORATE_SUBSCRIBER. Results below your min_confidence become UNKNOWN with the reason LOW_CONFIDENCE_MATCH.

Reason codes

CodeMeaning
SYNTAX_INVALIDThe address is not a valid email address.
NO_MXThe domain has no mail servers, so it cannot receive email.
MAILBOX_NOT_FOUNDThe mail server rejected the mailbox.
CATCH_ALL_DOMAINThe domain accepts mail for any mailbox, so the mailbox cannot be confirmed.
DISPOSABLE_DOMAINA temporary or disposable inbox provider.
ROLE_ACCOUNTA role address such as info@ or sales@ rather than a named person.
FREE_WEBMAILA free webmail provider such as Gmail, Outlook or iCloud.
CONSUMER_ISPA consumer internet provider mailbox such as BT Internet.
COMPANY_MATCHEDThe domain was matched to a UK registered company.
COMPANY_ACTIVEThe matched company is active on the Companies House register.
COMPANY_DISSOLVEDThe matched company has been dissolved.
COMPANY_IN_LIQUIDATIONThe matched company is in liquidation.
COMPANY_NOT_ACTIVEThe matched company has another status that is not active.
NOT_BODY_CORPORATEThe matched organisation is not a body corporate.
LLPThe matched company is a limited liability partnership (a body corporate).
SCOTTISH_PARTNERSHIPThe matched entity is a Scottish partnership (a body corporate).
PUBLIC_SECTOR_DOMAINA recognised UK public sector domain.
NO_UK_MATCHNo UK registered company was found for the domain.
MULTIPLE_CANDIDATESMore than one company could sit behind the domain.
LOW_CONFIDENCE_MATCHA match was found but below your confidence threshold, so the verdict was downgraded to UNKNOWN.
SHARED_OR_HOSTING_DOMAINA domain shared by many unrelated organisations, such as a hosting or co-working provider.
SUPPRESSED_CUSTOMER_LISTThe address or domain is on your suppression list.
CACHED_RESULTThe same address was checked in the last 30 days, so the stored result was returned.

Verify a batch

POST /verify/batch takes up to 100 items and returns the results synchronously, in the same order. Each item is { "email", "reference"? }, and each result has the same shape as a single verify. If one item fails, only that item comes back as { "reference", "error" }, with error set to plan_limit_reached or upstream_error; the rest still complete.

curl -X POST https://pecrcheck.emailmovers.services/api/v1/verify/batch \
  -H "Authorization: Bearer $PECRCHECK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "email": "a@firm1.co.uk", "reference": "c-1" },
      { "email": "b@gmail.com", "reference": "c-2" }
    ]
  }'
{
  "results": [
    { "audit_id": "pc_aud_...", "domain": "firm1.co.uk", "verdict": "CORPORATE_SUBSCRIBER", ... },
    { "audit_id": "pc_aud_...", "domain": "gmail.com", "verdict": "INDIVIDUAL_SUBSCRIBER", ... }
  ]
}

Audit records

GET /audit/{audit_id} returns the stored evidence record for a check. Records hold a SHA-256 hash of the address, never the plaintext, and are kept for 3 years by default.

curl https://pecrcheck.emailmovers.services/api/v1/audit/pc_aud_7mQ2xK9vR4tN8bLs \
  -H "Authorization: Bearer $PECRCHECK_API_KEY"

Suppressions

Add the addresses and whole domains that have opted out of your email. Any verify that hits your suppression list returns SUPPRESSED with the action DO_NOT_SEND and the reason SUPPRESSED_CUSTOMER_LIST.

  • GET /suppressions lists your suppressions.
  • POST /suppressions with { "email" } or { "domain" } adds one.
  • DELETE /suppressions with the same body removes one.
# Suppress one address
curl -X POST https://pecrcheck.emailmovers.services/api/v1/suppressions \
  -H "Authorization: Bearer $PECRCHECK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "opted.out@acme-widgets.co.uk" }'

# Suppress a whole domain
curl -X POST https://pecrcheck.emailmovers.services/api/v1/suppressions \
  -H "Authorization: Bearer $PECRCHECK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "domain": "acme-widgets.co.uk" }'

# Remove a suppression (same body as when it was added)
curl -X DELETE https://pecrcheck.emailmovers.services/api/v1/suppressions \
  -H "Authorization: Bearer $PECRCHECK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "domain": "acme-widgets.co.uk" }'

# List suppressions
curl https://pecrcheck.emailmovers.services/api/v1/suppressions \
  -H "Authorization: Bearer $PECRCHECK_API_KEY"

Usage

GET /usage returns your plan and billable lookups for the current period.

curl https://pecrcheck.emailmovers.services/api/v1/usage \
  -H "Authorization: Bearer $PECRCHECK_API_KEY"
{
  "plan": "starter",
  "period_start": "2026-10-01",
  "included": 5000,
  "used": 1240,
  "remaining": 3760
}

Errors

Errors return a JSON body with a machine readable error code and a human readable message.

{
  "error": "rate_limited",
  "message": "Too many requests. Retry after the number of seconds in the Retry-After header."
}
StatuserrorMeaning
400invalid_requestThe body is missing or malformed, for example no email field or more than 100 batch items.
401unauthorisedThe API key is missing, invalid or revoked.
402plan_limit_reachedYour plan has no lookups left this period.
429rate_limitedToo many requests. Wait for the number of seconds in the Retry-After header.
502upstream_errorA service we depend on failed. Retry later.

What counts as a lookup

  • Free webmail addresses and addresses with invalid syntax are not billable.
  • Every other address, meaning anything that reaches company matching, counts as one lookup.
  • Checking the same address again within 30 days returns the cached result (cached: true, reason CACHED_RESULT) and is not billable.
  • The billable field on each result tells you whether it counted.

See pricing for the lookups included in each plan.

Data protection

For lookups, Emailmovers Limited acts as your processor. Evidence records keep a SHA-256 hash of each address, not the plaintext. Addresses you check are never added to Emailmovers’ marketing database. See the privacy policy and terms of service.