Ruby email verification

Verify emails in Ruby with Verifly

Add email verification to a Ruby or Rails app with the standard net/http library and JSON — no gem to install. Verifly is an API-first, pay-as-you-go service that returns a clean JSON verdict you can branch on.

Verify one email in RubyAPI
require 'net/http'
require 'json'

uri = URI('https://verifly.email/api/v1/verify')
uri.query = URI.encode_www_form(email: 'user@example.com')

req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer vf_YOUR_KEY'

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
data = JSON.parse(res.body)
puts "#{data['result']} #{data['is_valid']}"

Real-time SMTP mailbox checks

Single, batch, and async bulk verification

Disposable, role account, and catch-all detection

Pay-as-you-go credits with no subscription lock-in

Search fit

Built for Ruby email verification

Use Verifly when you need a simple API, predictable pricing, and clean JSON results before emails hit your product, CRM, or campaign tool.

Validate emails in a Rails model or controller at signup
Clean an imported list inside a rake task
Filter leads in a Sidekiq worker before sending
Check addresses in a plain Ruby script with no dependencies

Email verification in Ruby and Rails

Ruby on Rails made email a first-class citizen of web apps, and with it came a first-class problem: the addresses users type in are frequently wrong, disposable, or dead. Rails validations and gems like validates_email_format_of check that an address is syntactically plausible, but syntax is not existence. A perfectly formatted address can point at a mailbox that was deleted, a domain that only issues throwaway addresses, or a role inbox nobody monitors — and you only discover it when the mail bounces.

Verifly turns that into a single HTTP call, and Ruby's standard library already has everything you need. net/http and json ship with the language, so there is no gem to add to your Gemfile and keep updated. You build a request, set a Bearer header, and JSON.parse the response into a hash with a result key of deliverable, undeliverable, or risky plus disposable, role, catch-all, and smtp flags. That maps naturally onto Ruby idioms — a case statement on the result, or a select block over an array of results.

The pay-as-you-go pricing suits both a Rails monolith and a one-off rake task. From $2 per 1,000 checks down to $0.60 per 1,000 at volume, there is no seat to justify and no plan to pick. Self-register for 100 free credits with no card and no captcha, keep the vf_ key in Rails credentials or an ENV var, and reuse it across models, workers, and scripts.

Batch-verify an array of emails in Ruby

When you have a list, POST it to /verify/batch rather than looping the single endpoint. Send a JSON body with an emails array and parse back a results array in order, which you can filter and partition with Ruby's Enumerable methods. This is the right tool for a rake task cleaning an imported CSV or a Sidekiq job preparing a campaign list.

Batch verification with net/http
require 'net/http'
require 'json'

emails = ['ada@example.com', 'info@some-domain.com', 'noreply@disposable.tld']
uri = URI('https://verifly.email/api/v1/verify/batch')

req = Net::HTTP::Post.new(uri)
req['Authorization'] = 'Bearer vf_YOUR_KEY'
req['Content-Type'] = 'application/json'
req.body = { emails: emails }.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
results = JSON.parse(res.body)['results']

clean = results.select { |r| r['result'] == 'deliverable' }
puts "Keeping #{clean.size} of #{results.size}"
results.each do |r|
  puts "drop: #{r['email']} (#{r['result']})" if r['disposable'] || r['role']
end

Validate at signup in a Rails model

The best place to verify in a Rails app is right where a User is created. A custom validation or a before_save hook that calls Verifly — with a read timeout so a slow probe never stalls the request, and fail-open behaviour on error so signups survive an outage — lets you reject disposable addresses and flag undeliverable ones before the record is committed.

Reject bad emails at signup
require 'net/http'
require 'json'

def email_ok?(email)
  uri = URI('https://verifly.email/api/v1/verify')
  uri.query = URI.encode_www_form(email: email)
  req = Net::HTTP::Get.new(uri)
  req['Authorization'] = 'Bearer vf_YOUR_KEY'

  res = Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 8) do |h|
    h.request(req)
  end
  data = JSON.parse(res.body)
  return false if data['disposable']
  data['result'] != 'undeliverable'
rescue StandardError
  true # fail open on network error
end

FAQ

Frequently asked questions

Do I need a gem to use Verifly in Ruby?

No. net/http and json are part of Ruby's standard library, so you can call Verifly with zero external gems. HTTParty or Faraday work too if your app already uses them, but they are optional.

How do I verify emails in a Rails model?

Add a custom validation or a before_save hook that calls Verifly and marks the record invalid on an undeliverable or disposable result. Use a read timeout and rescue to fail open so a network blip never blocks account creation.

What's the best way to verify a big list?

Send it to POST /api/v1/verify/batch as a JSON emails array from a rake task or Sidekiq job, rather than looping the single endpoint. You get one results array back to select and partition with Enumerable.

What does the parsed response look like?

JSON.parse returns a hash with result (deliverable, undeliverable, or risky), is_valid, and boolean flags disposable, role, catch_all, and smtp. A case statement on result plus a disposable check covers most decisions.

Should verification run in a background job?

For bulk cleaning, yes — put it in a Sidekiq or Active Job worker. For a single signup check it is fast enough to run inline, as long as you set a read timeout and fail open on error.

What does Ruby email verification cost?

Pay-as-you-go from $2 per 1,000 checks down to $0.60 per 1,000 at volume, with 100 free credits on self-register. No subscription, so a rake task and a production app share the same simple billing.