Docs

Contact Check

One call per address. The answer comes back with the rule quoted and a signed receipt.

Quick start

1. Get a free key. You can also call without one, with a smaller daily allowance.

2. Send the address, who you are and where you got it.

curl https://precleared.dev/api/v1/check \
  -H "Authorization: Bearer pc_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_email": "jane@acme.co.uk",
    "sender_country": "GB",
    "pitch": "Bookkeeping software for small firms",
    "address_source": "published",
    "company_number": "01234567"
  }'

Request fields

recipient_email or recipient_domain (one is required), sender_country (GB or US, default GB), pitch, address_source (published, bought, scraped, given or unknown; default published), recipient_country (two letters), company_number, pitch_relevant, existing_customer (default false), suppressed.

Response fields

verdict
ok_to_email, consent_needed, blocked or unknown.
confidence
high, medium or low. Medium usually means the legal form came from the website, not the register.
reasons
The rule that matched, with its text and source, followed by any notes.
rules_applied
The rule keys used. Look them up on /rules.
footer_text
Wording to include in the email footer, if the rule gives one.
next_step
What to do next, in one line.
facts
What we found: masked address, domain, country and where it came from, legal form and its source, company number, name and status, director first name, address type, syntax, mailbox record, disposable and suppressed flags.
receipt
Receipt id, time, request and response hashes, Ed25519 signature, key version and a verify URL.
rules_version
The version of the rule set used. It is also in the receipt.
usage
free_remaining_today and credits_remaining for the caller.
disclaimer
A fixed line. Decision support with sources, not legal advice.

Errors

Every error is JSON with an error code and a plain message.

  • 400 The body is not valid. The message says which field.
  • 401 The key is wrong or has been revoked.
  • 402 payment_required. Today's free checks are used and there are no credits. The body has buy_url.
  • 429 daily_limit. Keyless use is over for today. The body has get_key_url.

A check has a 25 second limit. If the register or the website is slow, the verdict is unknown with a note.

MCP

The MCP server runs over streamable HTTP at https://precleared.dev/mcp. It has two tools.

  • contact_check takes the same input as the API and returns the same JSON.
  • verify_receipt takes an id and returns the receipt.
{
  "mcpServers": {
    "precleared": {
      "url": "https://precleared.dev/mcp",
      "headers": { "Authorization": "Bearer pc_live_..." }
    }
  }
}

The header is optional. Without a key, the keyless daily allowance applies.

Verifying a receipt

Each receipt is signed with Ed25519 over the string request_hash.response_hash. Get the public key from /api/v1/public-key. It is base64 SPKI DER. The key version is in every receipt.

import { createPublicKey, verify } from "node:crypto";

const r = await (await fetch("https://precleared.dev/api/v1/receipt?id=cc_rcpt_...")).json();
const { public_key } = await (await fetch("https://precleared.dev/api/v1/public-key")).json();

const key = createPublicKey({ key: Buffer.from(public_key, "base64"), format: "der", type: "spki" });
const ok = verify(null, Buffer.from(`${r.request_hash}.${r.response_hash}`), key, Buffer.from(r.signature, "base64"));
console.log(ok ? "Signature verified" : "Signature does not match");

Allowances and pricing

  • No key: 10 checks a day per network.
  • Free key: 25 checks a day.
  • Pack: £39 for 2,000 checks. Used after the daily free checks. Never expire.

Days run on UK time.

Suppression list

A managed suppression list per key is coming soon. For now, pass suppressed: true when the address is on your own list.

Other resources

openapi.json · llms.txt · /api/v1/rules