Email Verification API for Ruby & Rails 2026 | BounceZero
Blog›Developer Guides

Email Verification API
Ruby & Rails Integration Guide 2026

Production-ready Ruby and Rails code examples for BounceZero email verification - from a simple Net::HTTP request to a full Rails custom validator, Devise registration hook, Sidekiq background worker, and batch CSV enrichment pattern.

By BounceZero Team |July 2026 |9 min read

Single Verification - Ruby (Net::HTTP, no gems)

verify.rb No gems required
require "net/http"
require "uri"
require "json"

API_KEY = ENV["BOUNCEZERO_API_KEY"]
BASE_URL = "https://api.bouncezero.io/api/v1"

def verify_email(email)
  uri  = URI("#{BASE_URL}/verify")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(uri)
  request["X-API-Key"]    = API_KEY
  request["Content-Type"]  = "application/json"
  request.body = { email: email }.to_json

  response = http.request(request)
  JSON.parse(response.body, symbolize_names: true)
end

result = verify_email("[email protected]")
puts result
# => {
#      email: "[email protected]",
#      score: 98,                    # 0-100
#      classification: "valid",      # "valid" | "invalid"
#      is_deliverable: true,
#      risk_level: "low",            # "low" | "medium" | "high"
#      checks: { syntax: true, domain_valid: true, not_disposable: true, ... },
#      metadata: { internal_classification: "verified", refunded: nil, ... }
#    }

Single Verification - Faraday Gem

verify_faraday.rb gem install faraday
require "faraday"
require "json"

API_KEY = ENV["BOUNCEZERO_API_KEY"]

def bouncezero_client
  Faraday.new("https://api.bouncezero.io") do |f|
    f.request  :json
    f.response :json, symbolize_names: true
    f.headers["X-API-Key"] = API_KEY
  end
end

def verify_email(email)
  response = bouncezero_client.post("/api/v1/verify", { email: email })
  response.body
end

result = verify_email("[email protected]")
puts result[:classification]                      # => "valid"
puts result[:score]                               # => 96
puts result.dig(:metadata, :internal_classification) # => "verified"

Rails Custom Validator

Add real-time verification to any Rails model attribute at validation time.

app/validators/bouncezero_email_validator.rb
require "net/http"
require "json"

class BounceZeroEmailValidator < ActiveModel::EachValidator
  API_KEY  = ENV["BOUNCEZERO_API_KEY"]
  ENDPOINT = URI("https://api.bouncezero.io/api/v1/verify")

  def validate_each(record, attribute, value)
    return if value.blank?

    result = call_api(value)
    return unless result

    if result.dig(:metadata, :internal_classification) == "disposable"
      record.errors.add(attribute, :disposable, message: "Please use a work or personal email address")
    elsif result[:classification] == "invalid" && !result.dig(:metadata, :refunded)
      # refunded = could not be verified (credit returned), so do not block on it
      record.errors.add(attribute, :invalid, message: "doesn't appear to be a valid email address")
    end
  rescue StandardError
    # Fail open on API errors - do not block signup
  end

  private

  def call_api(email)
    http    = Net::HTTP.new(ENDPOINT.host, ENDPOINT.port)
    http.use_ssl = true
    req = Net::HTTP::Post.new(ENDPOINT)
    req["X-API-Key"]    = API_KEY
    req["Content-Type"]  = "application/json"
    req.body = { email: email }.to_json
    res = http.request(req)
    JSON.parse(res.body, symbolize_names: true)
  end
end

# In your User model:
# validates :email, presence: true, bouncezero_email: true

Sidekiq Background Worker - Post-Signup Verification

Run verification asynchronously to avoid blocking the signup response. Flag the account for review if the email fails post-creation.

app/workers/email_verification_worker.rb gem install sidekiq
class EmailVerificationWorker
  include Sidekiq::Worker
  sidekiq_options retry: 2, queue: :verification

  def perform(user_id)
    user = User.find_by(id: user_id)
    return unless user

    result = BounceZeroService.verify(user.email)
    return unless result

    case result[:classification]
    when "invalid"
      user.update!(email_verified_at: nil, email_status: "invalid")
      # Optional: flag for manual review or send re-registration prompt
    when "valid"
      user.update!(email_verified_at: Time.current, email_status: "valid")
    end

    user.update!(
      email_disposable: result.dig(:metadata, :internal_classification) == "disposable",
      email_score: result[:score]
    )
  end
end

# Trigger from UsersController#create or Devise registrations_controller:
# EmailVerificationWorker.perform_async(@user.id)

API Response Fields

Field Type Values Use for
classification String valid / invalid Primary routing decision (binary)
score Integer 0 - 100 Confidence threshold for borderline decisions
is_deliverable Boolean true / false Quick send / suppress switch
risk_level String low / medium / high Flag medium-risk valids (e.g. catch-all) for review
checks.not_disposable Boolean true / false Block throwaway addresses at signup
metadata.internal_classification String verified / likely_valid / catch_all / invalid / risky / unknown / disposable / spamtrap / error Detailed reason behind the binary verdict
metadata.refunded Boolean true / null Could not be verified; credit auto-refunded

New to verification? Start with the complete email verification guide.

Frequently Asked Questions

How do I verify an email address in Ruby?

Use Net::HTTP (built-in) or Faraday to POST to https://api.bouncezero.io/api/v1/verify with your API key in the X-API-Key header and {email: address} as a JSON body. Parse the response and check the classification field: ‘valid’ or ‘invalid’. The detailed reason is in metadata.internal_classification.

How do I add email verification to a Rails signup form?

Create a custom ActiveModel::EachValidator that calls BounceZero during validation. Add validates :email, bouncezero_email: true to your User model. The validator adds errors to the email attribute for invalid addresses and disposable domains. Fail open on API errors to avoid blocking legitimate signups.

How do I use BounceZero with Devise in Rails?

Run verification post-signup in a Sidekiq worker triggered from a Devise after_sign_up hook. The worker calls BounceZero, updates the user’s email_status, and flags invalid accounts for review. Async avoids blocking the signup UX on an external API response.

Get your API key and start verifying in 2 minutes.

100 free credits on signup. No credit card. Instant access to the verification API. $3/1K thereafter - credits never expire.

Build with the BounceZero API

Endpoints, code samples, and language guides