Ruby SDK

Ruby email client gem

The official Mailpipe Ruby gem provides an expressive, idiomatic interface for sending and receiving email. It integrates natively with Rails ActionMailer, Sidekiq for background delivery, and any Rack-based web framework.

Installation

Install via RubyGems or add to your Gemfile:

terminal
gem install mailpipe
Gemfile
gem "mailpipe", "~> 1.0"

Then run:

terminal
bundle install

Requires Ruby 3.1 or later. The gem uses net/http from the standard library with no additional runtime dependencies.

Configuration

Configure the gem globally in an initializer (recommended for Rails):

config/initializers/mailpipe.rb
require "mailpipe"

Mailpipe.configure do |config|
  config.api_key    = ENV.fetch("MAILPIPE_API_KEY")
  config.timeout    = 30          # seconds, default: 30
  config.max_retries = 3          # retries on 5xx, default: 3
  config.logger     = Rails.logger # optional, for request logging
end

Or instantiate the client directly for scoped configuration:

client.rb
require "mailpipe"

# Per-instance client
client = Mailpipe::Client.new(
  api_key: ENV["MAILPIPE_API_KEY"],
  timeout: 10,
)

# Or use the global singleton after calling Mailpipe.configure
Mailpipe.client  # => Mailpipe::Client instance

Send Email

Send a transactional email using the global client or an instance:

send.rb
require "mailpipe"

# Using the global client (after Mailpipe.configure)
message = Mailpipe.messages.send(
  from: "noreply@yourdomain.com",
  to: ["user@example.com"],
  subject: "Welcome to our platform!",
  html: "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
  text: "Welcome! Thanks for signing up.",
)

puts "Sent: #{message.id}"
# => Sent: msg_01hx7k3p8n2qwerty

Send with CC, BCC, a named sender, and custom headers:

send_advanced.rb
message = Mailpipe.messages.send(
  from: { email: "invoices@acme.com", name: "Acme Billing" },
  to: ["customer@example.com"],
  cc: ["accountant@acme.com"],
  bcc: ["archive@acme.com"],
  reply_to: "billing@acme.com",
  subject: "Your invoice #INV-2024-001",
  html: invoice_html,
  text: invoice_text,
  headers: {
    "X-Invoice-Id" => "INV-2024-001"
  },
  tags: ["invoice", "billing"],
)

List Mailboxes

Retrieve mailboxes and enumerate messages with optional filters:

mailboxes.rb
# List all mailboxes
response = Mailpipe.mailboxes.list
response.data.each do |mailbox|
  puts "#{mailbox.email} — #{mailbox.unread_count} unread"
end

# List unread messages in a specific mailbox
messages = Mailpipe.messages.list(
  mailbox_id: "mbx_01hx7k3abc",
  unread: true,
  limit: 25
)

puts "Found #{messages.data.size} of #{messages.meta.total} messages"

messages.data.each do |msg|
  puts "[#{msg.received_at}] #{msg.subject} — from #{msg.from}"
end

# Paginate through all messages
page = Mailpipe.messages.list(limit: 50)
loop do
  page.data.each { |msg| process(msg) }
  break unless page.meta.has_more?
  page = Mailpipe.messages.list(limit: 50, offset: page.meta.next_offset)
end

Rails Integration

ActionMailer Adapter

Configure Rails to use Mailpipe as your ActionMailer delivery method:

config/environments/production.rb
Rails.application.configure do
  config.action_mailer.delivery_method = :mailpipe
  config.action_mailer.mailpipe_settings = {
    api_key: ENV.fetch("MAILPIPE_API_KEY"),
  }
end

Your existing mailers work unchanged:

app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  default from: "noreply@yourdomain.com"

  def welcome_email(user)
    @user = user
    @url  = new_session_url

    mail(
      to:      user.email,
      subject: "Welcome to #{Rails.application.name}!"
    )
  end

  def password_reset(user, token)
    @user  = user
    @token = token

    mail(
      to:      user.email,
      subject: "Reset your password"
    )
  end
end

# Deliver in a controller or background job
UserMailer.welcome_email(user).deliver_later
UserMailer.password_reset(user, token).deliver_now

Receiving Webhooks in Rails

Handle incoming email events with a dedicated webhook controller:

config/routes.rb
# config/routes.rb
post "/webhooks/mailpipe", to: "webhooks#mailpipe"
app/controllers/webhooks_controller.rb
class WebhooksController < ApplicationController
  # Skip CSRF protection for webhooks
  skip_before_action :verify_authenticity_token, only: :mailpipe

  def mailpipe
    payload   = request.body.read
    signature = request.headers["X-Mailpipe-Signature"]

    event = Mailpipe.webhooks.construct_event(
      payload,
      signature,
      secret: ENV.fetch("MAILPIPE_WEBHOOK_SECRET")
    )

    case event.type
    when "message.received"
      IncomingEmailJob.perform_later(event.data.to_h)
    when "message.bounced"
      BounceHandlerJob.perform_later(event.data.recipient)
    end

    head :ok
  rescue Mailpipe::WebhookSignatureError => e
    Rails.logger.warn "Invalid webhook signature: #{e.message}"
    head :bad_request
  end
end

Error Handling

All exceptions inherit from Mailpipe::Error and can be rescued individually or together:

error_handling.rb
require "mailpipe"

begin
  Mailpipe.messages.send(
    from: "noreply@yourdomain.com",
    to: ["user@example.com"],
    subject: "Hello",
    html: "<p>Hello</p>"
  )
rescue Mailpipe::AuthenticationError
  Rails.logger.error "Invalid Mailpipe API key"
rescue Mailpipe::RateLimitError => e
  Rails.logger.warn "Rate limited — retry after #{e.retry_after}s"
  # Re-enqueue Sidekiq job
  raise Sidekiq::LimitFetch::StopRetry if e.retry_after > 60
rescue Mailpipe::ValidationError => e
  Rails.logger.error "Validation failed: #{e.errors.inspect}"
rescue Mailpipe::NetworkError => e
  Rails.logger.error "Network error: #{e.message}"
  raise # re-raise for Sidekiq retry
rescue Mailpipe::Error => e
  Rails.logger.error "Mailpipe error #{e.status}: #{e.message} (#{e.request_id})"
end
Exception hierarchy
Mailpipe::Error
├── Mailpipe::APIError
│   ├── Mailpipe::AuthenticationError  # 401
│   ├── Mailpipe::PermissionError      # 403
│   ├── Mailpipe::NotFoundError        # 404
│   ├── Mailpipe::ValidationError      # 422
│   ├── Mailpipe::RateLimitError       # 429
│   └── Mailpipe::ServerError          # 5xx
├── Mailpipe::NetworkError
└── Mailpipe::WebhookSignatureError

API Reference

Explore the full REST API documentation with all available endpoints.

View API Reference

Webhooks

Receive real-time email events with webhook signature verification.

Webhook Guide

Need Help?

Our team is here to help. Reach out if you have any questions.

Contact Support