0.0
The project is in a healthy, maintained state
Rails integration for the Truelist.io email validation API. Validate email deliverability with a simple ActiveModel validator.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

truelist-rails

Free tier Email validation for Rails, powered by Truelist.io.

Gem Version CI

Validate email deliverability in your Rails models with a single line:

validates :email, deliverable: true

Truelist checks whether an email address actually exists and can receive mail, catching typos, disposable addresses, and invalid mailboxes before they hit your database.

Start free — 100 validations + 10 enhanced credits, no credit card required. Get your API key →

Installation

Add to your Gemfile:

gem "truelist-rails"

Then run:

bundle install

Quick Start

1. Configure your API key

Set the TRUELIST_API_KEY environment variable, or run the install generator:

rails generate truelist:install

This creates config/initializers/truelist.rb where you can configure the gem.

2. Add the validator

class User < ApplicationRecord
  validates :email, presence: true, deliverable: true
end

That's it. Invalid emails will now fail validation with a clear error message.

Configuration

Truelist.configure do |config|
  # Your Truelist API key (required).
  # Defaults to ENV["TRUELIST_API_KEY"].
  config.api_key = ENV["TRUELIST_API_KEY"]

  # API base URL. Change only for testing or proxying.
  config.base_url = "https://api.truelist.io"

  # Request timeout in seconds.
  config.timeout = 10

  # When true, raises Truelist::Error on API failures.
  # When false (default), returns an "unknown" result on errors,
  # allowing the validation to pass gracefully.
  config.raise_on_error = false

  # Whether "accept_all" emails (domains that accept all addresses) pass validation.
  config.allow_risky = true

  # Optional cache store for validation results.
  # Accepts any Rails-compatible cache store.
  config.cache_store = Rails.cache

  # How long to cache validation results (in seconds).
  config.cache_ttl = 1.hour
end

Validator Options

Basic usage

validates :email, deliverable: true

Reject accept_all emails

validates :email, deliverable: { allow_risky: false }

Custom error message

validates :email, deliverable: { message: "is not a valid email address" }

Combine options

validates :email, deliverable: { allow_risky: false, message: "doesn't look right" }

Use with other validators

validates :email, presence: true,
                  format: { with: URI::MailTo::EMAIL_REGEXP },
                  deliverable: true

The deliverable validator skips blank values, so pair it with presence: true if the field is required.

Working with Results Directly

Use the client to validate emails outside of model validations:

result = Truelist.validate("user@example.com")

result.state       # => "ok", "email_invalid", "accept_all", or "unknown"
result.sub_state   # => "email_ok", "is_disposable", "is_role", etc.
result.valid?      # => true when state is "ok" (or "accept_all" with allow_risky)
result.invalid?    # => true when state is "email_invalid"
result.accept_all? # => true when state is "accept_all"
result.unknown?    # => true when state is "unknown"

result.email        # => the validated email address
result.suggestion   # => suggested correction, if available
result.domain       # => email domain
result.canonical    # => local part of the email
result.mx_record    # => MX record for the domain
result.first_name   # => first name, if available
result.last_name    # => last name, if available
result.verified_at  # => timestamp of verification
result.disposable?  # => whether it's a disposable/temporary address (sub_state)
result.role?        # => whether it's a role address (sub_state)

Account Info

client = Truelist::Client.new
account = client.account

account["email"]                   # => "team@company.com"
account["name"]                    # => "Team Lead"
account["uuid"]                    # => "a3828d19-..."
account["account"]["payment_plan"] # => "pro"

Sub-states

Sub-state Meaning
email_ok Email is valid and deliverable
is_disposable Disposable/temporary email
is_role Role-based address (info@, admin@)
failed_smtp_check SMTP check failed
failed_mx_check Domain has no mail server
failed_spam_trap Known spam trap address
failed_no_mailbox Mailbox does not exist
failed_greylisted Server temporarily rejected (greylisting)
failed_syntax_check Email format is invalid
unknown_error Could not determine status

Caching

Enable caching to avoid redundant API calls for recently validated emails:

Truelist.configure do |config|
  config.cache_store = Rails.cache
  config.cache_ttl = 1.hour
end

The cache key is based on the lowercase, stripped email address. Any Rails-compatible cache store works (Redis, Memcached, file store, etc.).

Error Handling

By default, API errors (timeouts, rate limits, server errors) return an unknown result, allowing validation to pass. This prevents your forms from breaking when the API is unreachable.

To raise exceptions instead:

Truelist.configure do |config|
  config.raise_on_error = true
end

Exception classes:

  • Truelist::Error -- base error class
  • Truelist::ApiError -- unexpected API responses
  • Truelist::AuthenticationError -- invalid API key (401)
  • Truelist::RateLimitError -- rate limit exceeded (429)

Testing

Stub the API in your tests to avoid real HTTP calls. With WebMock:

# spec/support/truelist.rb
RSpec.configure do |config|
  config.before do
    stub_request(:post, "https://api.truelist.io/api/v1/verify_inline")
      .with(query: hash_including(email: /.+/))
      .to_return(
        status: 200,
        body: {
          emails: [{
            address: "user@example.com",
            email_state: "ok",
            email_sub_state: "email_ok"
          }]
        }.to_json,
        headers: { "Content-Type" => "application/json" }
      )
  end
end

Or stub at the client level:

allow(Truelist::Client).to receive(:new).and_return(
  instance_double(Truelist::Client, validate: Truelist::Result.new(email: "user@example.com", state: "ok"))
)

Requirements

  • Ruby >= 3.0
  • Rails >= 7.0 (ActiveModel / ActiveSupport)

Development

git clone https://github.com/Truelist-io-Email-Validation/truelist-rails.git
cd truelist-rails
bundle install
bundle exec rspec

Getting Started

Sign up for a free Truelist account to get your API key. The free plan includes 100 validations and 10 enhanced credits — no credit card required.

License

Released under the MIT License.