Introduction
If you have ever accidentally sent test emails to real customers, you know how painful that can be. SendPit eliminates the risk by giving every team a private SMTP mailbox that captures outgoing mail before it reaches the outside world. Unlike MailCatcher (which only runs locally) or Letter Opener (which only works in development), SendPit is a hosted service that works across every environment: development, CI, staging, and QA.
Because SendPit speaks standard SMTP, you do not need a special gem or SDK. Rails' built-in Action Mailer connects in minutes, and the same credentials work for plain Ruby scripts, Sinatra apps, and any other Ruby code that sends email.
This guide walks you through the complete setup: configuring Action Mailer, storing credentials securely, sending your first test email, handling multiple environments, using plain Ruby and Sinatra, writing tests, running inside Docker, and troubleshooting common errors.
Prerequisites
Before you begin, make sure you have:
- Ruby 3.0+ installed (
ruby -vto check) - Rails 6+ (if using Rails; the plain Ruby section works without it)
- A SendPit account with at least one mailbox created
- Your mailbox SMTP credentials (username starting with
mb_and a password) from the SendPit dashboard
Step 1: Configure Action Mailer
Open config/environments/development.rb and add the following SMTP settings inside the Rails.application.configure block:
# config/environments/development.rb
Rails.application.configure do
# ... other config ...
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.sendpit.com',
port: 587,
user_name: 'mb_a1b2c3d4e5f6g7h8',
password: 'your_sendpit_password_here',
authentication: :plain,
enable_starttls_auto: true
}
# Optional: raise delivery errors so you see failures immediately
config.action_mailer.raise_delivery_errors = true
end
Replace the user_name and password values with the credentials from your SendPit mailbox. That is all Rails needs -- save the file and restart your server.
Step 2: Store Credentials Securely
Hard-coding passwords in configuration files is fine for a quick test, but you should never commit them to version control. Rails gives you two good options.
Option A: Environment Variables
Set the variables in your shell, .env file (with the dotenv gem), or your hosting platform:
export SENDPIT_USERNAME="mb_a1b2c3d4e5f6g7h8"
export SENDPIT_PASSWORD="your_sendpit_password_here"
Then reference them in your configuration:
config.action_mailer.smtp_settings = {
address: 'smtp.sendpit.com',
port: 587,
user_name: ENV['SENDPIT_USERNAME'],
password: ENV['SENDPIT_PASSWORD'],
authentication: :plain,
enable_starttls_auto: true
}
Option B: Rails Credentials (Encrypted)
Rails 5.2+ includes an encrypted credentials file. Edit it with:
bin/rails credentials:edit
Add your SendPit credentials:
sendpit:
username: mb_a1b2c3d4e5f6g7h8
password: your_sendpit_password_here
Then reference them:
config.action_mailer.smtp_settings = {
address: 'smtp.sendpit.com',
port: 587,
user_name: Rails.application.credentials.dig(:sendpit, :username),
password: Rails.application.credentials.dig(:sendpit, :password),
authentication: :plain,
enable_starttls_auto: true
}
Step 3: Send a Test Email from the Rails Console
The fastest way to verify your setup is to fire off a quick email from the console:
bin/rails console
ActionMailer::Base.mail(
from: 'test@example.com',
to: 'dev@example.com',
subject: 'SendPit Test',
body: 'Hello from Rails console!'
).deliver_now
If everything is configured correctly the method returns without error. Open your SendPit dashboard and you will see the email waiting in your mailbox.
Using Action Mailer
For real applications you will want proper mailer classes. Generate one with:
bin/rails generate mailer UserMailer welcome_email
This creates app/mailers/user_mailer.rb and a view template. Flesh out the mailer:
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
def welcome_email(user)
@user = user
mail(
to: @user.email,
subject: "Welcome to #{Rails.application.config.app_name}"
)
end
end
Create the HTML template at app/views/user_mailer/welcome_email.html.erb:
<h1>Welcome, <%= @user.name %>!</h1>
<p>Your account is ready. Click below to get started:</p>
<p><%= link_to 'Go to Dashboard', dashboard_url %></p>
Send it from anywhere in your application:
UserMailer.welcome_email(@user).deliver_later
Using deliver_later queues the email through Active Job, which keeps your request fast. The email still routes through SendPit's SMTP server and appears in your mailbox.
Environment-Specific Configuration
Most teams want SendPit in development and staging but a real provider in production. Keep each environment separate:
# config/environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.sendpit.com',
port: 587,
user_name: ENV['SENDPIT_USERNAME'],
password: ENV['SENDPIT_PASSWORD'],
authentication: :plain,
enable_starttls_auto: true
}
# config/environments/staging.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.sendpit.com',
port: 587,
user_name: ENV['SENDPIT_STAGING_USERNAME'],
password: ENV['SENDPIT_STAGING_PASSWORD'],
authentication: :plain,
enable_starttls_auto: true
}
# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.your-production-provider.com',
port: 587,
user_name: ENV['PRODUCTION_SMTP_USERNAME'],
password: ENV['PRODUCTION_SMTP_PASSWORD'],
authentication: :plain,
enable_starttls_auto: true
}
Using separate SendPit mailboxes for development and staging lets each team inspect their own emails without interference.
Plain Ruby (Without Rails)
You do not need Rails to use SendPit. Ruby's standard library includes Net::SMTP:
require 'net/smtp'
message = <<~MESSAGE
From: sender@example.com
To: recipient@example.com
Subject: SendPit Plain Ruby Test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
This email was sent from a plain Ruby script via SendPit.
MESSAGE
smtp = Net::SMTP.new('smtp.sendpit.com', 587)
smtp.enable_starttls
smtp.start('localhost', 'mb_a1b2c3d4e5f6g7h8', 'your_sendpit_password', :plain) do |conn|
conn.send_message(message, 'sender@example.com', 'recipient@example.com')
end
puts 'Email sent successfully!'
The mail gem is a popular alternative that provides a friendlier interface:
require 'mail'
Mail.defaults do
delivery_method :smtp, {
address: 'smtp.sendpit.com',
port: 587,
user_name: 'mb_a1b2c3d4e5f6g7h8',
password: 'your_sendpit_password',
authentication: 'plain',
enable_starttls_auto: true
}
end
Mail.deliver do
from 'sender@example.com'
to 'recipient@example.com'
subject 'Hello from the Mail gem'
body 'Sent via SendPit!'
end
Sinatra
For Sinatra apps, the mail gem or pony gem both work well. Here is a minimal example with Pony:
# Gemfile
gem 'sinatra'
gem 'pony'
# app.rb
require 'sinatra'
require 'pony'
Pony.options = {
via: :smtp,
via_options: {
address: 'smtp.sendpit.com',
port: 587,
user_name: ENV['SENDPIT_USERNAME'],
password: ENV['SENDPIT_PASSWORD'],
authentication: :plain,
enable_starttls_auto: true
}
}
post '/contact' do
Pony.mail(
from: params[:email],
to: 'team@example.com',
subject: 'Contact Form',
body: params[:message]
)
'Message sent!'
end
All emails hit your SendPit mailbox instead of a real inbox, so you can test contact forms safely.
Testing with RSpec and Minitest
During automated tests you usually do not want to hit any SMTP server at all. Rails sets config.action_mailer.delivery_method = :test in config/environments/test.rb by default, which stores emails in ActionMailer::Base.deliveries instead of sending them.
RSpec Example
# spec/mailers/user_mailer_spec.rb
require 'rails_helper'
RSpec.describe UserMailer, type: :mailer do
describe '#welcome_email' do
let(:user) { create(:user, email: 'alice@example.com') }
let(:mail) { described_class.welcome_email(user) }
it 'renders the correct subject' do
expect(mail.subject).to eq("Welcome to #{Rails.application.config.app_name}")
end
it 'sends to the user email' do
expect(mail.to).to eq(['alice@example.com'])
end
it 'renders the greeting in the body' do
expect(mail.body.encoded).to include(user.name)
end
end
end
Minitest Example
# test/mailers/user_mailer_test.rb
require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test 'welcome email' do
user = users(:alice)
email = UserMailer.welcome_email(user)
assert_emails 1 do
email.deliver_now
end
assert_equal ['alice@example.com'], email.to
assert_match 'Welcome', email.subject
end
end
When you need an integration test that actually sends through SMTP (for example, in a CI smoke test), temporarily override the delivery method:
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
address: 'smtp.sendpit.com',
port: 587,
user_name: ENV['SENDPIT_CI_USERNAME'],
password: ENV['SENDPIT_CI_PASSWORD'],
authentication: :plain,
enable_starttls_auto: true
}
Docker Configuration
When running Rails inside Docker, pass your SendPit credentials as environment variables in docker-compose.yml:
# docker-compose.yml
services:
web:
build: .
environment:
SENDPIT_USERNAME: mb_a1b2c3d4e5f6g7h8
SENDPIT_PASSWORD: your_sendpit_password_here
ports:
- "3000:3000"
For production-like setups, use Docker secrets or a .env file:
# .env (add to .gitignore!)
SENDPIT_USERNAME=mb_a1b2c3d4e5f6g7h8
SENDPIT_PASSWORD=your_sendpit_password_here
services:
web:
build: .
env_file:
- .env
No special networking is required. Your container just needs outbound access to smtp.sendpit.com on port 587.
Troubleshooting
Net::SMTPAuthenticationError (535 Authentication failed)
- Double-check your username (starts with
mb_) and password in the SendPit dashboard. - Make sure you are copying the full credential strings without trailing whitespace.
- Verify you are using
authentication: :plain(not:loginor:cram_md5).
Net::OpenTimeout / Connection Timeout
- Confirm your network or firewall allows outbound connections on port 587.
- If you are behind a corporate proxy, configure Ruby's proxy settings or ask your network admin to allow SMTP traffic.
- Inside Docker, ensure the container has internet access (
docker compose exec web ping smtp.sendpit.com).
Connection Refused (Errno::ECONNREFUSED)
- Verify the address is
smtp.sendpit.comand the port is587. - A typo in the address or port is the most common cause.
Emails Not Appearing in SendPit
- Confirm the
deliver_nowordeliver_latercall completed without errors. - If using
deliver_later, make sure your Active Job backend (Sidekiq, Delayed Job, etc.) is running and processing jobs. - Check you are looking at the correct mailbox in the SendPit dashboard -- credentials are mailbox-specific.
SSL/TLS Errors (OpenSSL::SSL::SSLError)
- Make sure
enable_starttls_auto: trueis set. SendPit requires STARTTLS on port 587. - Update your Ruby and OpenSSL versions if you see certificate-related errors.
Next Steps
Your Rails application is now routing all outgoing email through SendPit. Here is what to explore next:
- Invite your team -- add teammates to your SendPit organization so everyone can inspect test emails.
- Create per-environment mailboxes -- separate mailboxes for dev, staging, and CI keep things organized.
- Integrate with CI -- add SendPit credentials to your CI environment variables so smoke tests can verify email delivery end-to-end.
- Check the full integration guide -- see all supported languages and advanced SMTP configuration at the main Integration Guide.