Skip to main content
Peopledat Logo

Browser widget

Improve form quality without turning email checks into an outage.

Run Quick verification from approved HTTPS origins, start with undeliverable results blocked, keep risky and unknown results advisory, and always fail open when the signal is unavailable.

Configure the exposure before copying code

  1. Create a named widget

    Use one widget per site or risk boundary so usage and revocation stay attributable.
  2. Add exact HTTPS origins

    Enter 1–20 complete origins such as https://www.example.com. Wildcards, paths, query strings, URL credentials, null, and HTTP are rejected.
  3. Set a daily hard credit cap

    Choose 1–50,000 credits. Start low, observe legitimate volume, then raise deliberately.
  4. Choose blocking categories

    The dashboard starts with undeliverable selected. With that default, risky and unknown results warn and allow submission. You may remove that block or explicitly add invalid syntax, disposable, spam-trap, or disabled results.
  5. Copy the public site key

    A key starts with pdw_. It is designed to be visible in browser code and is not a secret.

Install the script and bind a real form

The script automatically binds only forms marked with data-peopledat.

Complete minimal integration
<form action="/join" method="post" data-peopledat>
  <label for="work-email">Work email</label>
  <input id="work-email" name="email" type="email" required>
  <button type="submit">Continue</button>
</form>

<script
  src="https://peopledat.com/widget/v1.js"
  data-site-key="pdw_REPLACE_WITH_YOUR_SITE_KEY"
  defer>
</script>

  • Put data-peopledat on each form you want automatically checked.
  • Use an input[type=email] or input[name=email].
  • Keep your normal form action and server-side validation.
  • Load the script with defer so markup is available when it binds.
  • Use data-site-key on a form to override the script’s default key for that form.
  • The script adds subtle “Checked by PeopleDat” attribution when enabled.
  • The base binding does not render positive or warning result UI. Add your own listener if you want visible feedback.

Build optional feedback from the result event

Every completed check emits a bubbling peopledat:result event before an allowed form is resubmitted. The markup and listener below are custom feedback; the base snippet does not render them for you.

Custom positive, warning, and blocked feedback
<p id="email-feedback" role="status" aria-live="polite"></p>

<script>
  const form = document.querySelector('[data-peopledat]')
  const feedback = document.querySelector('#email-feedback')

  form.addEventListener('peopledat:result', (event) => {
    const { allow, status, warning } = event.detail

    feedback.dataset.state = !allow
      ? 'blocked'
      : status === 'deliverable'
        ? 'positive'
        : warning
          ? 'warning'
          : 'neutral'

    feedback.textContent = !allow
      ? 'Please use a deliverable email address.'
      : status === 'deliverable'
        ? 'Looks deliverable.'
        : warning
          ? 'We could not confirm this address, but you can continue.'
          : ''
  })
</script>

Coarse browser widget response statuses
StatusDefaultMeaning
deliverableAllowThe Quick result supports sending.
reviewWarn/allowA risky category needs judgment; blocks only when explicitly selected.
invalidBlockAn undeliverable result. New dashboard widgets block it by default; removing that selection makes it advisory.
unavailableAlways allowTimeout, outage, unknown, exclusion, credit/cap issue, or another inconclusive state.

With the dashboard default, risky results emit review with allow: true and warning: true; unknown results emit unavailable with the same allow/warning flags. A default-blocked undeliverable result emits invalid with allow: false.

The browser receives coarse reasons by design. It never receives provider internals, cache details, raw API credentials, or other workspace data.

Use the small JavaScript API for custom forms

The loaded script exposes an immutable window.PeopleDat object with version, verify, and bind.

Bind a form created after the script loads
const form = document.querySelector('#newsletter-form')
window.PeopleDat.bind(form)

Request an advisory result manually
const result = await window.PeopleDat.verify({
  siteKey: 'pdw_REPLACE_WITH_YOUR_SITE_KEY',
  email: '[email protected]',
  requestId: crypto.randomUUID()
})

if (result.status === 'unavailable') {
  // Fail open: continue your normal workflow.
}

Use a unique request ID for each visitor action. The automatic form binding creates one for you and prevents duplicate pending checks or resubmission loops.

Keep browser and server responsibilities separate

  • Treat the site key as public; never put a pd_live_… API key in browser code.
  • Keep normal server-side validation, abuse controls, consent checks, and authorization.
  • Use the widget only as a point-in-time email-quality signal.
  • Add https://peopledat.com to both script-src and connect-src in a strict Content Security Policy.
  • Do not send the result as proof of identity or mailbox ownership.
  • Monitor usage and pause/revoke a widget that shows unexpected volume.
Relevant CSP directives
Content-Security-Policy:
  script-src 'self' https://peopledat.com;
  connect-src 'self' https://peopledat.com;

Know exactly when the widget fails open

Timeouts, PeopleDat outages, provider failures, unknown/excluded results, exhausted credits, daily-cap denials, and other inconclusive states return an allowed unavailable result. The SDK also catches network, CORS, parsing, and abort errors and returns an allowed response.

PeopleDat uses a shorter server deadline than the browser timeout. If work completes too late to influence the visitor, the interaction is reconciled to zero billed credits.

Troubleshoot the widget

Nothing happens on submit

Confirm the form has data-peopledat, an email input, and the deferred script loaded without a CSP error. The script tag alone does not bind an unmarked form.

Every result is unavailable

Check that the exact page origin—including www/non-www and port—is active, the widget/entitlement is active, and connect-src permits peopledat.com.

The form submits twice or loops

Do not add a second submit handler that resubmits independently. Let PeopleDat.bind own its one approved resubmission.

A risky result is not blocked

That matches the dashboard default: only undeliverable starts selected. Risky results warn and allow unless you explicitly add a matching category; unknown and unavailable always warn and allow.

Unexpected credit use

Lower the hard daily cap, inspect origin/usage attribution, rotate by archiving the widget, and create a replacement site key.