Send email in Rails with an email API

How to send transactional email from Rails — Net::HTTP to Notify, no SMTP mailer required.

Send transactional email from Rails with an HTTPS call from a controller, mailer-style service, or Active Job. Keep the API key in credentials/env — never in views. You do not need Action Mailer’s SMTP delivery for this path.

Prerequisites

  • API key — authenticate every request with the x-api-key header
  • Verified domain — required for production sends from a custom from address
  • Rails 7+ recommended
export NOTIFY_API_KEY=your_api_key_here

Or in config/credentials.yml.enc / your host’s secret store.


Service object

# app/services/notify_mailer.rb
require 'net/http'
require 'json'
require 'uri'

class NotifyMailer
  class Error < StandardError; end

  SEND_URL = URI('https://notify.cx/api/email/send')

  def self.send_email(to:, subject:, message:, from: nil)
    from ||= ENV.fetch('NOTIFY_FROM', 'noreply@your-verified-domain.com')

    http = Net::HTTP.new(SEND_URL.host, SEND_URL.port)
    http.use_ssl = true

    request = Net::HTTP::Post.new(SEND_URL)
    request['Content-Type'] = 'application/json'
    request['x-api-key'] = ENV.fetch('NOTIFY_API_KEY')
    request.body = JSON.generate(
      from: from,
      to: to,
      subject: subject,
      message: message
    )

    response = http.request(request)
    unless response.is_a?(Net::HTTPSuccess)
      raise Error, "#{response.code}: #{response.body}"
    end

    JSON.parse(response.body)
  end
end

Controller example

# app/controllers/welcome_emails_controller.rb
class WelcomeEmailsController < ApplicationController
  def create
    email = params.require(:email)
    name = params[:name].presence || 'there'

    NotifyMailer.send_email(
      to: email,
      subject: 'Welcome',
      message: "<p>Hi #{ERB::Util.html_escape(name)},</p><p>Thanks for signing up.</p>"
    )

    render json: { ok: true }
  rescue NotifyMailer::Error => e
    render json: { error: e.message }, status: :bad_gateway
  end
end

Queue with Active Job

# app/jobs/send_notify_email_job.rb
class SendNotifyEmailJob < ApplicationJob
  queue_as :default

  def perform(to:, subject:, message:)
    NotifyMailer.send_email(to: to, subject: subject, message: message)
  end
end

# Dispatch
SendNotifyEmailJob.perform_later(
  to: user.email,
  subject: 'Reset your password',
  message: %(<p><a href="#{reset_url}">Reset password</a></p>)
)

Render ERB/Haml to a string when you want templates without a marketing ESP. Keep password-reset tokens in your app; Notify only delivers the HTML you send.

For a minimal Ruby (non-Rails) sample, see the Ruby guide.


Where to next?