API Documentation

Last updated 2026-04-27

Overview

IsTempMail is a real-time HTTP API that verifies whether an email address or domain is disposable, temporary, or otherwise unresolvable. It is built for sign-up forms, lead capture, payment flows, and anywhere you accept an email address from a user.

What it does

  • Checks any email or domain against a curated block list of 130k+ disposable providers, updated multiple times daily.
  • Detects domains that don’t resolve (typos, dead MX records).
  • Lets you maintain your own per-account block list and allow list (paid plans).
  • Lets you report suspicious domains for review.

Base URL

https://www.istempmail.com/api

All endpoint paths below are relative to this base URL. Responses are JSON.

Quick Start

1. Get your API token

Sign up, then copy your 32-character API token from the dashboard. The free plan gives you 200 checks/month — enough to integrate and test.

2. Make your first request

curl "https://www.istempmail.com/api/check/YOUR_TOKEN/mailinator.com"

Response:

{
  "name": "mailinator.com",
  "blocked": true
}

blocked: true means the domain is on the disposable list. Reject the sign-up, ask for another address, or flag the user for review — your call.

3. Check an email address (not just a domain)

curl "https://www.istempmail.com/api/check/YOUR_TOKEN/jane@gmail.com"

The API extracts and normalises the domain for you. Response:

{
  "name": "gmail.com",
  "blocked": false
}

That’s the whole API for the common case. Everything below is for managing your custom lists and integrating cleanly into production.

Authentication

All endpoints require your 32-character API token. Two authentication methods are supported:

Method Where the token goes Works with
Bearer token Authorization: Bearer {token} header All endpoints
Path token In the URL: /check/{token}/{name} /check only — quick alternative for one-line cURL or copy-paste testing, no headers required

Both methods accept the same token value and reach the same result. Treat the token as a secret — anyone with it can consume your quota and modify your custom lists. Rotate it from the dashboard if it leaks.

⚠ Don’t put path-token URLs in client-side JavaScript or mobile apps where users can read them. For browser/mobile use, proxy the call through your backend.

Endpoints

Check a domain or email

Returns the block status of a domain. If you pass an email, the local-part is stripped and only the domain is checked.

curl "https://www.istempmail.com/api/check/mailinator.com" \
  -H "Authorization: Bearer $ITM_TOKEN"

See sample code: Node.js · Next.js · Python · Ruby · Go · PHP · Cloudflare Worker · Express

Quick alternative — same endpoint, token in the path, no headers needed:

curl "https://www.istempmail.com/api/check/YOUR_TOKEN/mailinator.com"
Parameters
NameRequiredDescription
nameyesA domain (example.com) or full email (jane@example.com)
tokenyesYour 32-character API token. Pass via Authorization: Bearer header, or in the URL path as shown above.
Response 200
{
  "name": "example.com",
  "blocked": false,
  "unresolvable": true
}
FieldTypeDescription
namestringThe normalised domain that was checked (lowercase)
blockedbooleantrue if the domain is on the global or your custom block list
unresolvablebooleanOptional. Present and true only when the domain has no MX records (e.g. typo, dead domain). Treat as a soft signal — fine for warning, not always for hard-blocking

blocked reflects your effective view: your allow list overrides the global block list, and your block list adds to it.

Add a domain to your block list

Available on Standard plan and above. Adds a domain to your account’s custom block list, so future /check calls return blocked: true for that domain even if it isn’t on the global list.

curl -X POST "https://www.istempmail.com/api/block" \
  -H "Authorization: Bearer $ITM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain":"spam-domain.example","comment":"Reported by support 2026-04-21"}'

See sample code: Node.js · Python · Ruby · Go · PHP

Body
{
  "domain": "spam-domain.example",
  "comment": "Reported by support 2026-04-21"
}
FieldRequiredNotes
domainyesThe domain to block
commentnoFree-text note shown in your dashboard. Max 255 chars
Response 200
{
  "success": true,
  "message": "Domain spam-domain.example was added to your block list."
}

If the domain is already on the global block list, the response is still success: true but explains it wasn’t added to your custom list (no need — it’s already blocked for you).

Note: Custom-list entries are removed when a domain is added to the global block list. This keeps your list focused on entries the global list doesn’t cover.

Add a domain to your allow list

Available on Standard plan and above. Forces a domain to return blocked: false for your account, even if it appears on the global block list.

curl -X POST "https://www.istempmail.com/api/allow" \
  -H "Authorization: Bearer $ITM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain":"partner.example"}'

See sample code: Node.js · Python · Ruby · Go · PHP

Body, comment rules, and response shape are identical to /block.

Response 200
{
  "success": true,
  "message": "The domain partner.example was added to your allow list."
}

If the domain is already on the global allow list, the response is still success: true but explains it wasn’t added to your custom list (no need — it’s already allowed for you).

Report a suspicious domain

Submit a domain for review by the IsTempMail team. Available on all plans, including free. Use this when you spot a disposable provider that isn’t on the global block list yet.

curl -X POST "https://www.istempmail.com/api/report" \
  -H "Authorization: Bearer $ITM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain":"new-temp-mail.example","comment":"Hit our signup form 50 times in 1 hour"}'

See sample code: Node.js · Python · Ruby · Go · PHP

Body
{
  "domain": "new-temp-mail.example",
  "comment": "Hit our signup form 50 times in 1 hour"
}
Response 200
{
  "success": true,
  "message": "Thank you for reporting new-temp-mail.example. It will be reviewed by our team and blocked if necessary."
}

If the domain has already been reviewed, you’ll get a global_allowlist or global_blocklist response so you can decide whether to add it to your custom list anyway.

What happens next
  1. Manual review. A member of the IsTempMail team examines the domain — MX records, registration patterns, provider signals, and the context you supplied in comment.
  2. Block or allow decision. The domain is added to the global block list (if confirmed disposable) or the global allow list (if it’s a legitimate provider).
  3. Email notification. You receive an email at the address on your account with the final decision and a short rationale.

Response Formats

Success (check)
{ "name": "example.com", "blocked": false }
Success (block / allow / report)
{ "success": true, "message": "..." }
Errors

All errors follow the same shape:

{
  "success": false,
  "error": "error_code",
  "error_description": "Human-readable explanation."
}

Legacy check errors omit the success field but carry the same error and error_description.

HTTPWhen
400Malformed JSON, missing/invalid domain field, comment over 255 chars
401Missing Authorization header, invalid token
403Plan restriction (custom lists not on your plan), expired account, negative balance
429Monthly request quota exceeded
500Server error — retry with exponential backoff
Common error codes
CodeWhen
app_errorGeneric, see error_description
unauthorizedAuth failed
plan_restrictionEndpoint requires a higher plan
global_allowlistReported domain already on global allow list (returned by /report)
global_blocklistReported domain already on global block list (returned by /report)

Rate Limits & Quotas

Quotas are measured as total requests over a rolling 30-day window, not per minute or per day. There are no burst limits — make calls as fast as you want, as long as the rolling total stays under your plan limit. Every API call counts against your quota, including repeated checks of the same domain — there is no server-side deduplication.

PlanRequests / 30 daysCustom block & allow list
Free200
Standard5,000
Plus15,000
Pro50,000
MaxUnlimited

When you exceed your quota:

  • The API returns 429 Too Many Requests.
  • We send you a notification email (at most once per day, not per request).
  • The limit takes effect immediately. Upgrade your plan to restore service.

If you anticipate a spike (a launch, a campaign), upgrade in advance — overage is not billed automatically except on the Max plan.

Sample Code

Pick a language, copy the Setup snippet once, then drop in only the endpoint snippets you actually need (Check, Block, Allow, Report). All examples assume your token is in the ITM_TOKEN environment variable — never hard-code it.

cURL

Bare HTTP requests from your terminal — ideal for testing, debugging, and ad-hoc shell pipelines.

Setup
export BASE_URL="https://www.istempmail.com/api"
export ITM_TOKEN="your_32_character_api_token"
AUTH=(-H "Authorization: Bearer $ITM_TOKEN")
JSON=(-H "Content-Type: application/json")
Check
curl "$BASE_URL/check/mailinator.com" "${AUTH[@]}"
Block
curl -X POST "$BASE_URL/block" "${AUTH[@]}" "${JSON[@]}" \
  -d '{"domain":"spam-domain.example","comment":"Repeated abuse"}'
Allow
curl -X POST "$BASE_URL/allow" "${AUTH[@]}" "${JSON[@]}" \
  -d '{"domain":"partner.example"}'
Report
curl -X POST "$BASE_URL/report" "${AUTH[@]}" "${JSON[@]}" \
  -d '{"domain":"new-temp-mail.example"}'

Node.js (native fetch, Node 18+)

Plain fetch against the API — works in any backend Node runtime (Express, Fastify, Hono, NestJS).

Setup
const BASE_URL = 'https://www.istempmail.com/api';
const headers = {
  Authorization: `Bearer ${process.env.ITM_TOKEN}`,
  'Content-Type': 'application/json',
};
Check
const email = 'jane@mailinator.com';
const res = await fetch(`${BASE_URL}/check/${encodeURIComponent(email)}`, { headers });
const data = await res.json();
if (data.blocked) throw new Error('Disposable email');
Block
await fetch(`${BASE_URL}/block`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ domain: 'spam-domain.example', comment: 'Repeated abuse' }),
});
Allow
await fetch(`${BASE_URL}/allow`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ domain: 'partner.example' }),
});
Report
await fetch(`${BASE_URL}/report`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ domain: 'new-temp-mail.example' }),
});

Next.js Server Action (TypeScript)

App Router pattern — type-safe wrappers you import from your form actions. Token never reaches the client.

Setup
'use server';

const BASE_URL = 'https://www.istempmail.com/api';
const headers = () => ({
  Authorization: `Bearer ${process.env.ITM_TOKEN!}`,
  'Content-Type': 'application/json',
});
Check
type CheckResponse = { name: string; blocked: boolean; unresolvable?: boolean };

export async function validateEmail(email: string) {
  const res = await fetch(`${BASE_URL}/check/${encodeURIComponent(email)}`, {
    headers: headers(),
    cache: 'no-store',
  });
  const data = (await res.json()) as CheckResponse;
  if (data.blocked) return { ok: false, reason: 'Please use a permanent email address.' };
  if (data.unresolvable) return { ok: false, reason: "That domain doesn't look right — typo?" };
  return { ok: true };
}
Block
export async function blockDomain(domain: string, comment?: string) {
  await fetch(`${BASE_URL}/block`, {
    method: 'POST',
    headers: headers(),
    body: JSON.stringify({ domain, comment }),
  });
}
Allow
export async function allowDomain(domain: string) {
  await fetch(`${BASE_URL}/allow`, {
    method: 'POST',
    headers: headers(),
    body: JSON.stringify({ domain }),
  });
}
Report
export async function reportDomain(domain: string, comment?: string) {
  await fetch(`${BASE_URL}/report`, {
    method: 'POST',
    headers: headers(),
    body: JSON.stringify({ domain, comment }),
  });
}

Python

Uses the requests library. The shape is identical with httpx or stdlib urllib.request.

Setup
import os
import requests

BASE_URL = 'https://www.istempmail.com/api'
HEADERS  = {'Authorization': f'Bearer {os.environ["ITM_TOKEN"]}'}
Check
email = 'jane@mailinator.com'
r = requests.get(f'{BASE_URL}/check/{email}', headers=HEADERS, timeout=5)
r.raise_for_status()
if r.json().get('blocked'):
    raise ValueError('Disposable email')
Block
requests.post(f'{BASE_URL}/block', headers=HEADERS,
    json={'domain': 'spam-domain.example', 'comment': 'Repeated abuse'})
Allow
requests.post(f'{BASE_URL}/allow', headers=HEADERS,
    json={'domain': 'partner.example'})
Report
requests.post(f'{BASE_URL}/report', headers=HEADERS,
    json={'domain': 'new-temp-mail.example'})

Ruby

Standard library only (net/http) — no gem dependency. A small istempmail_verify helper covers all four endpoints.

Setup
require 'net/http'
require 'json'
require 'uri'

BASE_URL = 'https://www.istempmail.com/api'
TOKEN    = ENV.fetch('ITM_TOKEN')

def istempmail_verify(method:, path:, body: nil)
  uri = URI("#{BASE_URL}#{path}")
  req = (method == :post ? Net::HTTP::Post : Net::HTTP::Get).new(uri)
  req['Authorization'] = "Bearer #{TOKEN}"
  if body
    req['Content-Type'] = 'application/json'
    req.body = JSON.generate(body)
  end
  res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
  JSON.parse(res.body)
end
Check
email = 'jane@mailinator.com'
data  = istempmail_verify(method: :get, path: "/check/#{URI.encode_www_form_component(email)}")
raise 'Disposable email' if data['blocked']
Block
istempmail_verify(method: :post, path: '/block',
            body: { domain: 'spam-domain.example', comment: 'Repeated abuse' })
Allow
istempmail_verify(method: :post, path: '/allow', body: { domain: 'partner.example' })
Report
istempmail_verify(method: :post, path: '/report', body: { domain: 'new-temp-mail.example' })

Go

Idiomatic net/http — drop into a Go module to wrap the API. No third-party dependencies.

Setup
package itm

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
    "os"
)

const BaseURL = "https://www.istempmail.com/api"

func istempmailVerify(method, path string, body any) (*http.Response, error) {
    var buf *bytes.Buffer
    if body != nil {
        b, _ := json.Marshal(body)
        buf = bytes.NewBuffer(b)
    } else {
        buf = bytes.NewBuffer(nil)
    }
    req, err := http.NewRequest(method, BaseURL+path, buf)
    if err != nil {
        return nil, err
    }
    req.Header.Set("Authorization", "Bearer "+os.Getenv("ITM_TOKEN"))
    if body != nil {
        req.Header.Set("Content-Type", "application/json")
    }
    return http.DefaultClient.Do(req)
}
Check
type CheckResult struct {
    Name         string `json:"name"`
    Blocked      bool   `json:"blocked"`
    Unresolvable bool   `json:"unresolvable,omitempty"`
}

func CheckEmail(email string) (*CheckResult, error) {
    resp, err := istempmailVerify(http.MethodGet, fmt.Sprintf("/check/%s", url.PathEscape(email)), nil)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    var r CheckResult
    return &r, json.NewDecoder(resp.Body).Decode(&r)
}
Block
func Block(domain, comment string) error {
    resp, err := istempmailVerify(http.MethodPost, "/block", map[string]string{
        "domain": domain, "comment": comment,
    })
    if err == nil {
        resp.Body.Close()
    }
    return err
}
Allow
func Allow(domain string) error {
    resp, err := istempmailVerify(http.MethodPost, "/allow", map[string]string{"domain": domain})
    if err == nil {
        resp.Body.Close()
    }
    return err
}
Report
func Report(domain, comment string) error {
    resp, err := istempmailVerify(http.MethodPost, "/report", map[string]string{
        "domain": domain, "comment": comment,
    })
    if err == nil {
        resp.Body.Close()
    }
    return err
}

PHP

No-dependency setup using file_get_contents with a stream context. Swap in Guzzle or Symfony HttpClient if you prefer.

Setup
$baseUrl = 'https://www.istempmail.com/api';
$token   = getenv('ITM_TOKEN');

function istempmail_verify(string $method, string $path, ?array $body = null): array {
    global $baseUrl, $token;
    $opts = [
        'method' => $method,
        'header' => 'Authorization: Bearer ' . $token,
    ];
    if ($body !== null) {
        $opts['header']  .= "\r\nContent-Type: application/json";
        $opts['content']  = json_encode($body);
    }
    $response = file_get_contents($baseUrl . $path, false, stream_context_create(['http' => $opts]));
    if ($response === false) {
        throw new RuntimeException('IsTempMail request failed');
    }
    return json_decode($response, true);
}
Check
$email = 'jane@mailinator.com';
$data  = istempmail_verify('GET', '/check/' . rawurlencode($email));
if ($data['blocked'] ?? false) {
    throw new RuntimeException('Disposable email');
}
Block
istempmail_verify('POST', '/block', ['domain' => 'spam-domain.example', 'comment' => 'Repeated abuse']);
Allow
istempmail_verify('POST', '/allow', ['domain' => 'partner.example']);
Report
istempmail_verify('POST', '/report', ['domain' => 'new-temp-mail.example']);

Java

Java 11+ standard library only (java.net.http.HttpClient) — no external dependency. Pair with Jackson or your JSON library of choice for response parsing.

Setup
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse.BodyHandlers;

static final String BASE_URL = "https://www.istempmail.com/api";
static final HttpClient HTTP = HttpClient.newHttpClient();

static HttpRequest.Builder istempmailVerify(String path) {
    return HttpRequest.newBuilder()
        .uri(URI.create(BASE_URL + path))
        .header("Authorization", "Bearer " + System.getenv("ITM_TOKEN"))
        .header("Content-Type", "application/json");
}
Check
String email = URLEncoder.encode("jane@mailinator.com", StandardCharsets.UTF_8);
HttpRequest req = istempmailVerify("/check/" + email).GET().build();
HttpResponse res = HTTP.send(req, BodyHandlers.ofString());
// parse res.body() with Jackson/Gson; check for "blocked": true
Block
String body = "{\"domain\":\"spam-domain.example\",\"comment\":\"Repeated abuse\"}";
HTTP.send(istempmailVerify("/block").POST(BodyPublishers.ofString(body)).build(),
          BodyHandlers.ofString());
Allow
HTTP.send(istempmailVerify("/allow")
              .POST(BodyPublishers.ofString("{\"domain\":\"partner.example\"}")).build(),
          BodyHandlers.ofString());
Report
HTTP.send(istempmailVerify("/report")
              .POST(BodyPublishers.ofString("{\"domain\":\"new-temp-mail.example\"}")).build(),
          BodyHandlers.ofString());

C# / .NET

.NET 6+ — HttpClient from the BCL plus System.Text.Json. No NuGet packages required.

Setup
using System.Net.Http;
using System.Net.Http.Json;
using System.Net.Http.Headers;

const string BaseUrl = "https://www.istempmail.com/api";

var http = new HttpClient { BaseAddress = new Uri(BaseUrl + "/") };
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("ITM_TOKEN"));
Check
var email = Uri.EscapeDataString("jane@mailinator.com");
var data  = await http.GetFromJsonAsync>($"check/{email}");
if ((bool)data!["blocked"]) throw new Exception("Disposable email");
Block
await http.PostAsJsonAsync("block",
    new { domain = "spam-domain.example", comment = "Repeated abuse" });
Allow
await http.PostAsJsonAsync("allow", new { domain = "partner.example" });
Report
await http.PostAsJsonAsync("report", new { domain = "new-temp-mail.example" });

Rust

Using reqwest (blocking or async) and serde_json. The async variant is shown below; swap .await for blocking sync calls if you prefer.

Setup
use reqwest::Client;
use serde_json::{json, Value};
use std::env;

const BASE_URL: &str = "https://www.istempmail.com/api";

fn istempmail_verify(client: &Client, method: reqwest::Method, path: &str) -> reqwest::RequestBuilder {
    client.request(method, format!("{BASE_URL}{path}"))
        .bearer_auth(env::var("ITM_TOKEN").expect("ITM_TOKEN not set"))
}
Check
let client = Client::new();
let email  = urlencoding::encode("jane@mailinator.com");
let data: Value = istempmail_verify(&client, reqwest::Method::GET, &format!("/check/{email}"))
    .send().await?
    .json().await?;
if data["blocked"].as_bool().unwrap_or(false) {
    return Err("Disposable email".into());
}
Block
istempmail_verify(&client, reqwest::Method::POST, "/block")
    .json(&json!({"domain": "spam-domain.example", "comment": "Repeated abuse"}))
    .send().await?;
Allow
istempmail_verify(&client, reqwest::Method::POST, "/allow")
    .json(&json!({"domain": "partner.example"}))
    .send().await?;
Report
istempmail_verify(&client, reqwest::Method::POST, "/report")
    .json(&json!({"domain": "new-temp-mail.example"}))
    .send().await?;

Cloudflare Worker

Edge-validate signups before they reach your origin. Store the API token as a Worker secret with Wrangler.

Setup
wrangler secret put ITM_TOKEN
# paste your 32-character API token when prompted
const BASE_URL = 'https://www.istempmail.com/api';

const istempmailVerify = (env, path, init = {}) => fetch(`${BASE_URL}${path}`, {
  ...init,
  headers: {
    Authorization: `Bearer ${env.ITM_TOKEN}`,
    'Content-Type': 'application/json',
    ...init.headers,
  },
});
Check
export default {
  async fetch(request, env) {
    const { email } = await request.json();
    const res = await istempmailVerify(env, `/check/${encodeURIComponent(email)}`,
                                       { cf: { cacheTtl: 60, cacheEverything: true } });
    const data = await res.json();
    if (data.blocked) {
      return Response.json({ error: 'Disposable email' }, { status: 400 });
    }
    return fetch('https://your-origin.example/signup', request);
  },
};
Block
await istempmailVerify(env, '/block', {
  method: 'POST',
  body: JSON.stringify({ domain: 'spam-domain.example', comment: 'Repeated abuse' }),
});
Allow
await istempmailVerify(env, '/allow', {
  method: 'POST',
  body: JSON.stringify({ domain: 'partner.example' }),
});
Report
await istempmailVerify(env, '/report', {
  method: 'POST',
  body: JSON.stringify({ domain: 'new-temp-mail.example' }),
});

Express

Signup-form guard plus admin routes for managing your custom lists.

Setup
const BASE_URL = 'https://www.istempmail.com/api';

const istempmailVerify = (path, init = {}) => fetch(`${BASE_URL}${path}`, {
  ...init,
  headers: {
    Authorization: `Bearer ${process.env.ITM_TOKEN}`,
    'Content-Type': 'application/json',
    ...init.headers,
  },
});
Check (signup-form guard)
app.post('/signup', async (req, res) => {
  const { email } = req.body;
  try {
    const result = await (await istempmailVerify(`/check/${encodeURIComponent(email)}`)).json();
    if (result.blocked) return res.status(400).json({ error: 'Please use a permanent email address.' });
    if (result.unresolvable) return res.status(400).json({ error: "That domain doesn't look right — typo?" });
  } catch (err) {
    console.error('IsTempMail check failed', err); // fail-open
  }
  // ...continue signup
});
Block
app.post('/admin/block-domain', adminOnly, async (req, res) => {
  await istempmailVerify('/block', {
    method: 'POST',
    body: JSON.stringify({ domain: req.body.domain, comment: req.body.comment }),
  });
  res.sendStatus(204);
});
Allow
app.post('/admin/allow-domain', adminOnly, async (req, res) => {
  await istempmailVerify('/allow', { method: 'POST', body: JSON.stringify({ domain: req.body.domain }) });
  res.sendStatus(204);
});
Report
app.post('/admin/report-domain', adminOnly, async (req, res) => {
  await istempmailVerify('/report', { method: 'POST', body: JSON.stringify({ domain: req.body.domain }) });
  res.sendStatus(204);
});

WordPress

Install the free Block Temporary Email plugin. Drop in your API token, pick the forms you want to protect (registration, comments, WooCommerce checkout, Gravity Forms, etc.) and you’re done — no code required.

FAQ

How fresh is the block list?

Updated multiple times per day. We see 20 to 50 new disposable providers and domains each day.

Can I check an email locally without hitting the API?

Not available with the regular paid plans. Local enterprise deployments are available on request.

What happens if your API is down?

Decide your fail policy in your integration: fail-open (let the signup through) or fail-closed (block until the API responds). Most customers fail-open and rely on downstream checks.

Will you tell me why a domain is blocked?

Not currently. Domains are flagged based on an aggregate of signals and manual review. The check endpoint returns a yes/no answer only.

Does blocked: false guarantee the address exists?

No. It guarantees the domain isn’t a known disposable provider. Use unresolvable: true to spot dead domains, but a positive blocked: false doesn’t promise the inbox accepts mail.

Can I check multiple domains in one request?

You can use the Bulk check in feature through the Dashboard. Just copy and paste your domains, and click once to get all verified. For now, send one request per domain — the API is fast enough that this is rarely a bottleneck.

Do you log the emails I check?

We never log email addresses. We discard the local part before the actual verification step and do not store it. We do keep logs of the domain for the rolling 30-day quota window. See our privacy policy for details.

How do I rotate my token?

From your dashboard. The old token stops working immediately, so update your integrations first. Multiple tokens per account are available in enterprise plans – talk to sales if interested.

What happens if my subscription lapses or my card fails?

Paddle subscribers get a 7-day grace period after the expiry date — the API keeps working while the retry happens. After that, requests return 403 "Your account has expired." until you renew. Manual (non-subscription) accounts have no grace period; the API stops at the expiry date.

For credit card failures, we will retry to charge. If the payment keeps failing, your subscription will be disabled.

Do you have an SLA?

We offer SLAs for entrprise customers. Please talk to sales for more information.

Is there a Zapier / Make integration?

Our API is easy to use on both platforms via the generic HTTP step. Just provide your token and you are good to go.

Get started for free

Sign up and get your API token in seconds — no credit card required.

↑ Back to top