← Back to home

Developer API

One integration, one question answered: can I send to this address without bouncing? A full check gives a strict yes/no - catch-alls, disposables and unverifiable mailboxes all count as "no", so your bounce rate stays protected. For signup and login forms, fast mode flags bad addresses in well under a second, for free.

Free plan: 100 full verifications every month, with full API access. Free on every plan: fast checks, repeat checks within 24 hours, invalid-syntax answers, /v1/account and test keys.

Create your API key

OpenAPI 3 spec: /v1/openapi.json - import it into Postman, Insomnia or your client generator. Jump to code examples.

Support

Questions, billing, account deletion, privacy requests or a problem with the API or the ChatGPT plugin? Email hello@mailrambo.com or humblepoc@gmail.com. Please include your account email and, for API issues, the endpoint and the error code you received. Never send passwords or full API keys.

See also: Privacy policy · Terms of service · Pricing.

MailRambo for ChatGPT

Existing MailRambo customers can check email addresses directly in ChatGPT. The plugin is in review by OpenAI and will appear in the ChatGPT plugin directory once approved.

Connect your account

When ChatGPT first uses MailRambo it opens a MailRambo sign-in page. Sign in with your normal MailRambo account (never in the chat), review the permissions and choose a maximum number of full-check attempts for the connection (0–10; 0 blocks full checks). Then click Approve connection. The connection lasts up to 30 days; disconnect any time in ChatGPT settings.

What it can do

It cannot send email, buy credits or change your plan, and results never prove identity or consent.

Common messages

Free tools (no key needed)

Try the same checks in your browser before you integrate, or share them with teammates. Each tool page shows the matching API call.

Domain & DNS checks

Email address checks

Record generators

Official SDKs

Thin, typed clients with automatic retries, retry-safe batches (idempotency keys added for you) and one error type. Both read MAILRAMBO_API_KEY from the environment.

# Node.js 18+ (zero dependencies, TypeScript types) npm install mailrambo import { MailRambo } from "mailrambo"; const mr = new MailRambo(); const { deliverable, reason } = await mr.verify("jane@acme.com"); await mr.verify("jane@gmial.com", { mode: "fast" }); // free, < 1s: { deliverable: false, reason: "possible_typo", suggestion: "jane@gmail.com" }
# Python 3.8+ (sync and asyncio) pip install mailrambo from mailrambo import MailRambo mr = MailRambo() result = mr.verify("jane@acme.com") mr.verify("jane@gmial.com", mode="fast") # free, < 1s

The mode option needs SDK 0.2 or newer (PyPI 0.2.0; npm 0.2.1 is rolling out through npm's review, so npm may still install 0.1.0 for a short while).

npm · Node source · PyPI · Python source

No-code: n8n

Verify emails inside n8n workflows with the MailRambo community node: Verify Email (Mode Fast for a free pre-filter, or Full with optional full detail), Start Batch, Get Batch and Get Account. In n8n go to Settings → Community Nodes → Install and enter:

n8n-nodes-mailrambo

Add your key as a MailRambo API credential; mr_test_ keys work for building workflows for free. npm

Code examples

Keep your key in an environment variable (MAILRAMBO_KEY) and call the API from your server - never from the browser.

# Single address curl -X POST https://www.mailrambo.com/v1/verify \ -H "Authorization: Bearer $MAILRAMBO_KEY" \ -H "Content-Type: application/json" \ -d '{"email": "jane@acme.com"}' # Signup form: free fast check (syntax, typos, MX, disposable) in well under a second curl -X POST "https://www.mailrambo.com/v1/verify?mode=fast" \ -H "Authorization: Bearer $MAILRAMBO_KEY" \ -H "Content-Type: application/json" \ -d '{"email": "jane@gmial.com"}' # Batch (retry-safe with Idempotency-Key), then poll curl -X POST https://www.mailrambo.com/v1/verify/batch \ -H "Authorization: Bearer $MAILRAMBO_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"emails": ["jane@acme.com", "info@corp.io"]}' curl https://www.mailrambo.com/v1/verify/batch/BATCH_ID \ -H "Authorization: Bearer $MAILRAMBO_KEY" # Remaining credits curl https://www.mailrambo.com/v1/account \ -H "Authorization: Bearer $MAILRAMBO_KEY"
// Node 18+ (built-in fetch) import { randomUUID } from "node:crypto"; const BASE = "https://www.mailrambo.com/v1"; const headers = { Authorization: `Bearer ${process.env.MAILRAMBO_KEY}`, "Content-Type": "application/json", }; async function call(path, init = {}) { const res = await fetch(BASE + path, { ...init, headers: { ...headers, ...init.headers } }); const body = await res.json(); if (!res.ok) throw new Error(`${body.error}: ${body.message}`); return body; } // Single address const { deliverable, reason } = await call("/verify", { method: "POST", body: JSON.stringify({ email: "jane@acme.com" }), }); // Signup form: free fast check - reject when deliverable === false, show suggestion const fast = await call("/verify?mode=fast", { method: "POST", body: JSON.stringify({ email: "jane@gmial.com" }), }); if (fast.deliverable === false) console.log(fast.reason, fast.suggestion); // "possible_typo" "jane@gmail.com" // Batch, then poll until completed const { batch_id } = await call("/verify/batch", { method: "POST", headers: { "Idempotency-Key": randomUUID() }, body: JSON.stringify({ emails: ["jane@acme.com", "info@corp.io"] }), }); let batch; do { await new Promise((r) => setTimeout(r, 3000)); batch = await call(`/verify/batch/${batch_id}`); } while (batch.status !== "completed"); console.log(batch.results); // Remaining credits const { credits_remaining } = await call("/account");
# pip install requests import os, time, uuid import requests BASE = "https://www.mailrambo.com/v1" s = requests.Session() s.headers["Authorization"] = f"Bearer {os.environ['MAILRAMBO_KEY']}" def call(method, path, **kw): r = s.request(method, BASE + path, timeout=30, **kw) body = r.json() if not r.ok: raise RuntimeError(f"{body['error']}: {body['message']}") return body # Single address res = call("POST", "/verify", json={"email": "jane@acme.com"}) print(res["deliverable"], res["reason"]) # Signup form: free fast check fast = call("POST", "/verify", params={"mode": "fast"}, json={"email": "jane@gmial.com"}) if fast["deliverable"] is False: print(fast["reason"], fast["suggestion"]) # possible_typo jane@gmail.com # Batch, then poll until completed batch_id = call("POST", "/verify/batch", json={"emails": ["jane@acme.com", "info@corp.io"]}, headers={"Idempotency-Key": str(uuid.uuid4())})["batch_id"] while (batch := call("GET", f"/verify/batch/{batch_id}"))["status"] != "completed": time.sleep(3) print(batch["results"]) # Remaining credits print(call("GET", "/account")["credits_remaining"])

Better Auth plugin

Screen email/password signups before creating a user or sending a confirmation email. Our server-only plugin uses mode=fast, with no verification credits charged.

npm install better-auth-mailrambo@0.1.0 better-auth@1.7.7
import { betterAuth } from "better-auth"; import { mailramboEmailCheck } from "better-auth-mailrambo"; import { existingAuthOptions } from "./auth-options"; // Your app's existing configuration. export const auth = betterAuth({ ...existingAuthOptions, plugins: [ ...(existingAuthOptions.plugins ?? []), mailramboEmailCheck(), // Reads server-side MAILRAMBO_API_KEY. ], });

Signup continues if MailRambo times out or returns an API error. Known syntax, typo, disposable-domain and mail-domain failures block signup. The default timeout is 2 seconds, with no automatic retries; keep your existing email-confirmation and abuse-control settings.

The package requires Better Auth 1.7.7 and Node.js 22 or later (tested on 22.23.3 and 26.7.0). Check compatibility before changing an existing app's auth version; do not force a peer-dependency conflict. Covers /sign-up/email only, not OAuth, OTP, magic links or email changes. Fast mode never confirms mailbox existence. Both live and test keys run real fast checks. Keep the key server-side: screening sends the signup address to MailRambo over HTTPS.

Runtime errors - including an invalid or revoked key - fail open, so monitor configuration separately. Missing credentials or invalid options throw at startup. Direct server signup callers must catch Better Auth's APIError; HTTP callers receive MAILRAMBO_EMAIL_REJECTED with status 400.

Complete Better Auth setup guide · npm package · Source and error handling. This is a MailRambo integration, not a built-in or endorsed Better Auth plugin.

Authentication

Create a key on the API Keys page and send it as a Bearer token. Keys start with mr_live_ (or mr_test_ for test mode) and are shown only once at creation - we store only a hash.

Authorization: Bearer mr_live_...

A full check costs 1 credit per address, drawn from the same balance as your dashboard. Every plan - including Free (100 a month) - can use the API. Fast checks, repeats within 24 hours and invalid-syntax answers are free.

Verify a single address

POST /v1/verify
curl -X POST https://www.mailrambo.com/v1/verify \ -H "Authorization: Bearer mr_live_..." \ -H "Content-Type: application/json" \ -d '{"email": "jane@acme.com"}'

Response (200):

{ "email": "jane@acme.com", "deliverable": true, "reason": "mailbox_exists", "credits_remaining": 483 }

For quick tests, GET /v1/verify?email=jane@acme.com returns the same response. Prefer POST in production: query strings end up in proxy and server logs, and email addresses are personal data.

Syntactically invalid input is answered for free - deliverable: false, reason: "invalid_syntax", no credit charged, and credits_remaining is null.

Fast mode for signup forms (mode=fast) - free

Add ?mode=fast (or "mode": "fast" in the body) for an instant check that never contacts the mailbox: standards-based syntax, domain typos, MX records, disposable providers and role addresses. It is free and typically answers in well under a second, so you can call it inline on every signup or login form.

curl -X POST "https://www.mailrambo.com/v1/verify?mode=fast" \ -H "Authorization: Bearer mr_live_..." \ -H "Content-Type: application/json" \ -d '{"email": "jane@gmial.com"}' { "email": "jane@gmial.com", "mode": "fast", "deliverable": false, "reason": "possible_typo", "suggestion": "jane@gmail.com", "checks": { "mx": true, "disposable": true, "role_account": false, "free_email": true }, "credits_remaining": null }

Fast mode can prove an address is bad but never that the mailbox exists, so deliverable is false when a check fails (invalid_syntax, possible_typo, disposable, no_mx) and null otherwise. Show suggestion as "Did you mean…?". Run a full check later (e.g. before your first marketing send) for a confirmed yes/no.

Free repeats

Checking the same address again within 24 hours is free and instant: the answer comes from your earlier check, with "cached": true and credits_remaining: null. Results are kept for 7 days (1 day for catch_all, unverifiable and inbox_full, which can change quickly).

Full detail (?detail=full)

Add ?detail=full (or "detail": "full" in the POST body) to get the intelligence behind the answer: lead grade, inbox provider, flags and the domain's DNS authentication. Same price - 1 credit, and also returned on free repeats. Single full checks only: ignored with mode=fast, and not available for batches or test keys.

{ "email": "jane@acme.com", "deliverable": true, "reason": "mailbox_exists", "credits_remaining": 482, "detail": { "grade": "A", "score": 92, "inbox_provider": "Google Workspace", "flags": { "free_email": false, "role_account": false, "disposable": false, "catch_all": false, "mailbox_exists": true }, "dns": { "mx": true, "mx_hosts": ["aspmx.l.google.com"], "spf": true, "dmarc_policy": "reject", "dkim_selectors": ["google"], "bimi": false, "ptr": true } } }

grade, score, inbox_provider and dns are null if the domain's DNS could not be read; deliverable is unaffected.

Verify a batch (up to 200)

POST /v1/verify/batch
curl -X POST "https://www.mailrambo.com/v1/verify/batch" \ -H "Authorization: Bearer mr_live_..." \ -H "Content-Type: application/json" \ -d '{"emails": ["jane@acme.com", "info@corp.io"], "name": "August list"}'

Response (202) - one credit per submitted address is charged up front:

{ "batch_id": "task_8fa2...", "emails_submitted": 2, "status": "processing", "credits_remaining": 481 }

If any address is syntactically invalid the whole batch is rejected with 400 invalid_emails and nothing is charged.

Safe retries: send an Idempotency-Key header (any unique string up to 255 chars, e.g. a UUID). Retrying with the same key and body within 24 hours returns the original response (with Idempotent-Replayed: true) instead of starting - and charging - a second batch.

curl -X POST https://www.mailrambo.com/v1/verify/batch \ -H "Authorization: Bearer mr_live_..." \ -H "Idempotency-Key: 5f0c9a2e-7b1d-4c3e-9a8f-2d6b1e4c7a90" \ -H "Content-Type: application/json" \ -d '{"emails": ["jane@acme.com", "info@corp.io"]}'

Poll for results

GET /v1/verify/batch/{batch_id}
curl "https://www.mailrambo.com/v1/verify/batch/task_8fa2..." \ -H "Authorization: Bearer mr_live_..."

While running, status is "processing" with progress 0–100. When "completed", results holds one verdict per address:

{ "batch_id": "task_8fa2...", "status": "completed", "progress": 100.0, "total": 2, "checked": 2, "results": [ { "email": "jane@acme.com", "deliverable": true, "reason": "mailbox_exists" }, { "email": "info@corp.io", "deliverable": false, "reason": "catch_all" } ] }

Poll every few seconds; large lists can take a few minutes. Batches also appear on your dashboard History page.

Account & credits

GET /v1/account

Check your plan and remaining credits before sending work. Free - no credit is charged.

curl https://www.mailrambo.com/v1/account \ -H "Authorization: Bearer mr_live_..."
{ "plan": "starter", "plan_name": "Starter", "status": "active", "credits_remaining": 2642, "credits_total": 1000, "pack_credits": 2000, "period_end": "2026-10-29T00:00:00+00:00", "cancel_at_period_end": false }

credits_remaining is everything you can spend now: what's left of this period's plan credits plus pack_credits (from credit packs, which never expire). credits_total is the plan's allowance for the period. period_end is when plan credits reset (may be null on the Free plan).

Test mode

Create a test key (mr_test_...) on the API Keys page to build your integration for free. Test keys never contact mail servers and never use credits; batches complete immediately. The answer is chosen by the part before the @ (any domain works, +tags are ignored):

Addressdeliverablereason
deliverable@example.comtruemailbox_exists
role@example.comtruerole_account
disposable@ · spamtrap@ · inbox_full@ · mailbox_disabled@ · catch_all@ · unverifiable@falsesame as the name
not_found@ or anything elsefalsemailbox_not_found

Invalid syntax still returns invalid_syntax. mode=fast with a test key runs the real fast checks (they're free anyway). /v1/account shows your real balance.

Reason codes

The closed set of values reason can take. Treat anything with deliverable: false as "do not send". deliverable: null only appears in fast mode: nothing wrong was found, but the mailbox was not checked.

reasondeliverableMeaning
mailbox_existstrueMailbox confirmed to accept mail.
role_accounttrueDeliverable, but a role inbox (info@, sales@). Consider filtering these for cold outreach.
invalid_syntaxfalseNot a valid email address. Free - never charged.
disposablefalseTemporary/throwaway provider.
spamtrapfalseKnown spam trap - sending damages your sender reputation.
inbox_fullfalseMailbox is full and soft-bounces.
mailbox_disabledfalseMailbox disabled by the provider.
catch_allfalseThe domain accepts every recipient, so this specific mailbox cannot be confirmed.
mailbox_not_foundfalseMailbox does not exist - would hard-bounce.
unverifiablefalseCould not be confirmed (greylisting, timeouts). Fail-closed.
possible_typofalsemode=fast only: the domain looks like a typo of a popular provider; see suggestion.
no_mxfalsemode=fast only: the domain has no mail server.
fast_check_passednullmode=fast only: no problem found; the mailbox itself was not checked.

Errors

All errors use a flat envelope: {"error": "<code>", "message": "<human readable>", ...}.

HTTPerrorWhen
401missing_api_key · invalid_api_key · api_key_revokedNo key, an unknown key, or a revoked key.
402insufficient_credits · subscription_inactiveOut of credits or subscription inactive. Includes credits_remaining (and credits_required for batches).
400invalid_request · invalid_emailsMalformed request (including an unknown mode or detail value), or a batch containing invalid addresses (lists up to 10 offenders; nothing charged).
403plan_not_allowed · not_available_on_rapidapiBatches are not included in your plan, or the endpoint is not offered through the RapidAPI gateway (single verify only there).
404not_foundNo batch with this id on your account.
409idempotency_in_progressA request with the same Idempotency-Key is still running - retry shortly.
422idempotency_key_reusedThe Idempotency-Key was already used with a different body.
429rate_limitedRate limit exceeded - back off and retry.
503provider_unavailable · temporarily_unavailableVerification backend unavailable. Charged credits are refunded automatically - retry safely.

Rate limits

EndpointLimit (per key)
/v1/verify?mode=fast600 / minute (10/s) - free, answers in well under a second
/v1/verify (full check)600 / minute requests; sustained full checks are fair-use at about 5 per second per account
/v1/verify/batch30 / minute (up to 200 addresses each)
/v1/verify/batch/{batch_id}600 / minute
/v1/account300 / minute

Signup and login forms: a full check talks to the recipient's mail server and usually takes 1–5 seconds. For forms, call mode=fast inline (syntax, typos, MX, disposable, role - free and instant) and run the full check afterwards, or only when the fast check passes. Repeat checks of the same address within 24 hours are free and instant.

Lists: use the batch endpoint - 30 calls a minute is up to 6,000 addresses a minute. On 429, back off and retry; both SDKs do this for you. Need a higher sustained rate? Email hello@mailrambo.com.

Billing summary

• 1 credit per full check, shared with your dashboard balance. Plan credits reset each period; credit-pack credits never expire.
• Free: mode=fast checks, repeat checks of the same address within 24 hours, syntactically invalid addresses, /v1/account, and everything with a test key.
• Batches charge all submitted addresses up front; catch-all and unverifiable results are still verification work and are not refunded.
• Provider outages (503) automatically refund the affected credits.

See pricing Create your API key