Language SDK

ActionMailer SMTP config is a nightmare

SMTP settings get nullified on load. Ruby 3.0 breaks SSL verification. Emails fail silently with no errors. Sidekiq bulk sends take 40 minutes instead of seconds. Ark uses HTTP—no SMTP, clear errors, works every time.

26
MCP tools
Sub-second
Delivery
99.9%
Inbox rate
$0.50
Per 1K emails

ActionMailer fails in ways you can't debug

ActionMailer's SMTP integration is fragile. Config assigned after load gets silently ignored. Ruby 3.0+ breaks SSL certificate handling that worked in 2.7. raise_delivery_errors defaults to false, so failures disappear. And when you finally get email working, Sidekiq bulk sends are mysteriously slow.

  • ×SMTP settings nullified on ActionMailer::Base load—config assigned in after_initialize silently ignored
  • ×Ruby 3.0+ breaks SSL certificate verification that worked in 2.7 with identical code
  • ×raise_delivery_errors defaults to false—emails fail with no indication
  • ×Sidekiq bulk email: 10,000 emails takes 40+ minutes (should be seconds)

HTTP API instead of SMTP

Ark sends email over HTTPS. No SMTP host/port/auth config to break. No SSL certificate debugging. Errors are clear and immediate. Bulk sends are fast because each request is independent.

No SMTP config—one API key, works in any Rails version
Errors raise immediately with clear messages (no silent failures)
Sidekiq bulk sends: thousands of emails in seconds, not minutes
Same behavior in development and production (no config mismatch)
2 minutes

Replace ActionMailer SMTP in 2 minutes

gem install, set one environment variable, send. No EMAIL_HOST, EMAIL_PORT, EMAIL_USE_TLS, EMAIL_USE_SSL confusion.

1

Add the gem

Add to Gemfile. Works with Ruby 3.0+.

# Gemfile
gem "ark-email"

# Then:
bundle install
2

Set your API key

One credential. Use Rails credentials or environment variable.

# config/credentials.yml.enc (via rails credentials:edit)
ark_api_key: ark_live_xxxxxx

# Or environment variable:
export ARK_API_KEY=ark_live_xxxxxx
3

Send email

Returns message ID on success. Raises on error (no silent failures).

require "ark"

ark = Ark::Client.new(api_key: Rails.application.credentials.ark_api_key)

response = ark.emails.send(
  from: "[email protected]",
  to: "[email protected]",
  subject: "Welcome!",
  html: "<h1>You're in.</h1>"
)
puts response.id  # Delivery confirmed

Code examples

Copy and paste to get started quickly.

Rails service object (clean pattern)
# app/services/email_service.rb
class EmailService
  def initialize
    @ark = Ark::Client.new(api_key: Rails.application.credentials.ark_api_key)
  end

  def welcome(user)
    # Returns response with ID, raises on error
    @ark.emails.send(
      from: "[email protected]",
      to: user.email,
      subject: "Welcome, #{user.name}!",
      html: render_template("welcome", user: user)
    )
  end

  private

  def render_template(name, locals = {})
    ApplicationController.render(
      template: "emails/#{name}",
      layout: "email",
      locals: locals
    )
  end
end

# Usage: EmailService.new.welcome(user)
Sidekiq job (fast bulk sends)
# app/jobs/send_email_job.rb
class SendEmailJob
  include Sidekiq::Job

  # Ark is fast—each job completes in ~100ms instead of 2-5s with SMTP
  def perform(to:, subject:, html:)
    ark = Ark::Client.new(api_key: Rails.application.credentials.ark_api_key)

    ark.emails.send(
      from: "[email protected]",
      to: to,
      subject: subject,
      html: html
    )
  end
end

# Bulk send 10,000 emails:
# With ActionMailer SMTP: 40+ minutes (SMTP handshake per email)
# With Ark HTTP: ~2 minutes (parallel HTTP requests)
users.each do |user|
  SendEmailJob.perform_async(
    to: user.email,
    subject: "Weekly digest",
    html: render_digest(user)
  )
end
Sinatra (works outside Rails)
# app.rb
require "sinatra"
require "ark"

# Works anywhere—not tied to Rails conventions
ark = Ark::Client.new(api_key: ENV["ARK_API_KEY"])

post "/contact" do
  content_type :json

  data = JSON.parse(request.body.read)

  begin
    ark.emails.send(
      from: "[email protected]",
      to: "[email protected]",
      reply_to: data["email"],
      subject: "Contact form: #{data["subject"]}",
      text: data["message"]
    )
    { success: true }.to_json
  rescue Ark::Error => e
    # Clear error—you know exactly what failed
    status 500
    { error: e.message }.to_json
  end
end

What you can build

Escape ActionMailer SMTP config hell

No more debugging smtp_settings that get nullified, SSL certificates that break between Ruby versions, or config that works locally but fails in production.

Fast Sidekiq bulk sends

Each Ark HTTP request completes in ~100ms. Sidekiq can parallelize thousands of emails. Compare to SMTP: 2-5 seconds per email, single connection, 40+ minute bulk sends.

No more silent failures

ActionMailer defaults raise_delivery_errors to false. Emails fail and you never know. Ark raises clear exceptions—you'll always know what went wrong.

Non-Rails Ruby apps

ActionMailer is tied to Rails. Ark works in Sinatra, Hanami, Roda, or plain Ruby scripts. Same API everywhere.

Why developers choose Ark

No SMTP configuration

One API key replaces EMAIL_HOST, EMAIL_PORT, EMAIL_USE_TLS, EMAIL_USE_SSL, and authentication config.

Clear error handling

Ark raises exceptions with specific error messages. No more silent failures or cryptic SMTP codes.

Thread-safe for Puma/Sidekiq

Client is thread-safe by default. Works correctly in threaded web servers and background job processors.

Sorbet types included

Full Sorbet RBI files for type-safe development. IDE autocomplete and type checking.

What you get with Ark

Automatic SPF, DKIM, DMARC
Real-time webhooks
Suppression management
Unlimited domains
Unlimited team members
$2.50 (5,000 emails) welcome credit
No monthly fees

Frequently asked questions

Why is ActionMailer SMTP so fragile?

ActionMailer's SMTP integration has timing issues (settings assigned after load get ignored), SSL handling differences between Ruby versions, and poor defaults (raise_delivery_errors is false). These aren't bugs—they're documented behavior that's easy to get wrong. HTTP APIs don't have these issues.

Why is Sidekiq bulk email slow with ActionMailer?

ActionMailer over SMTP requires a full SMTP handshake per email (2-5 seconds). Sidekiq processes jobs in parallel, but each job waits on SMTP. Ark uses HTTP (~100ms per request), so Sidekiq can blast through thousands of emails quickly.

Can I use this alongside ActionMailer?

Yes. You can migrate incrementally—use Ark for new email sends while ActionMailer handles existing mailers. Or replace ActionMailer entirely.

What about deliverability and bounce handling?

Ark handles SPF, DKIM, and DMARC automatically when you verify your domain. Bounce events are available via webhooks. ActionMailer gives you none of this—you're on your own for authentication and bounce handling.

Is it thread-safe?

Yes. Ark's Ruby client is thread-safe. Use it in Puma, Sidekiq, or any concurrent Ruby environment without synchronization issues.

What does it cost?

$0.50 per 1,000 emails. No monthly fees. $2.50 welcome credit (5,000 emails). Most Rails apps run for months on the free credit.

gem install ark-email

No ActionMailer SMTP nightmares. No silent failures. Fast Sidekiq bulk sends. 2 minutes to first email.