Skip to main content

Getting started

Making your first verification

Verify your first email address with the Kawaa API, from curl or your own Node.js or Python code, or try one in the dashboard.

Single email verification

Verify an email with a POST request that carries an Idempotency-Key from its first attempt:

Verification is charged when the request is accepted, even if its response is lost. To make a request safe to retry, create an Idempotency-Key (any unique token, such as a UUID) before the first attempt, send it on that attempt, and send the same key on every retry. The request is then charged once:

# Requires Python 3. Run once per verification; on retry, run only curl again.
KEY=$(python3 -c 'import uuid; print(uuid.uuid4())') || exit 1
test -n "$KEY" || exit 1

curl -X POST https://api.kawaa.com/v1/verify \
  -H "X-Api-Key: ev_your_api_key" \
  -H "Idempotency-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "john@example.com"}'

A repeat that Kawaa had already accepted answers with "status": "pending" and "credits_used": 0; read its result from GET /v1/jobs/{job_id}. Safe retries has the details.

From your own code

Or use the Node.js or Python package

From version 0.2.0, Kawaa's packages handle the key for you: verify() makes one Idempotency-Key per call and sends it on every retry. Install one with npm install kawaa or pip install kawaa. If you have 0.1.0 or 0.1.1, upgrade: they retry without a key, so a retry after a lost answer can be charged again. SDKs & libraries has the details.

Both samples make one key for the verification before the first attempt, and send it again on each retry after a dropped connection or a 5xx. Set KAWAA_API_KEY to your API key before running them.

Node.js

Node.js 18 or later. Save this as verify.mjs and run node verify.mjs. The .mjs extension makes Node run it as a module, which import and top-level await need, whatever your package.json says.

// verify.mjs
import { randomUUID } from 'node:crypto';

async function verify(email, attempts = 3) {
  // One key for this verification, sent on every attempt.
  const key = randomUUID();
  for (let attempt = 1; ; attempt++) {
    try {
      const response = await fetch('https://api.kawaa.com/v1/verify', {
        method: 'POST',
        headers: {
          'X-Api-Key': process.env.KAWAA_API_KEY,
          'Idempotency-Key': key,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email }),
        signal: AbortSignal.timeout(30000),
      });
      if (response.status < 500 || attempt === attempts) return await response.json();
    } catch (error) {
      if (attempt === attempts) throw error; // no answer on any attempt
    }
    await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
  }
}

const body = await verify('john@example.com');
if (!body.success) throw new Error(body.error.code + ': ' + body.error.message);
console.log(body.data.status); // 'invalid'

Python

Uses the requests package (pip install requests). Save this as verify.py and run python verify.py.

import os
import time
import uuid

import requests


def verify(email, attempts=3):
    # One key for this verification, sent on every attempt.
    key = str(uuid.uuid4())
    for attempt in range(1, attempts + 1):
        try:
            response = requests.post(
                "https://api.kawaa.com/v1/verify",
                headers={"X-Api-Key": os.environ["KAWAA_API_KEY"], "Idempotency-Key": key},
                json={"email": email},
                timeout=30,
            )
            if response.status_code < 500 or attempt == attempts:
                return response.json()
        except (requests.exceptions.RequestException, ValueError):
            if attempt == attempts:
                raise  # no answer on any attempt
        time.sleep(attempt)


body = verify("john@example.com")
if not body["success"]:
    raise RuntimeError(body["error"]["code"] + ": " + body["error"]["message"])
print(body["data"]["status"])  # 'invalid'

A "pending" status means the check is still running, or a retry reached a request Kawaa had already accepted: read the result from GET /v1/jobs/{job_id} with the same X-Api-Key.

Testing in the dashboard

You can also test email verification directly in your dashboard without writing any code. Go to the Dashboard and use the single verification form.

Something wrong or missing here?

Tell us what to fix. Your email goes to the support team with this article's title already filled in.

Send feedback

Still need help?

Email support@kawaa.com. If your question is about a bulk job, include its job ID from the dashboard.

Contact support