Send emails with Ruby on Rails
Learn how to send transactional emails using PostStack and Ruby on Rails.
Ruby on Rails ships with ActionMailer and Net::HTTP in the standard library, so you can talk to PostStack without adding a gem. For simple transactional flows, a thin wrapper around `Net::HTTP::Post` is the smallest viable integration. For Rails-native ergonomics — previews, layouts, mailer tests — configure PostStack as the SMTP delivery method instead.
1. Install the SDK
# No external gems needed — uses the standard library2. Initialize the client
require 'net/http'
require 'json'
require 'uri'
API_KEY = ENV['POSTSTACK_API_KEY']
BASE_URL = 'https://api.poststack.dev'3. Send an email
require 'net/http'
require 'json'
require 'uri'
api_key = ENV['POSTSTACK_API_KEY']
uri = URI('https://api.poststack.dev/emails')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = "Bearer #{api_key}"
request['Content-Type'] = 'application/json'
request.body = {
from: 'hello@yourdomain.com',
to: ['user@example.com'],
subject: 'Hello from Ruby!',
html: '<h1>Welcome!</h1>'
}.to_json
response = http.request(request)
puts response.body4. Handle errors
Ruby on Rails idioms for error handling, retries, and structured logging when calling the PostStack API.
require 'net/http'
require 'json'
require 'uri'
class PoststackError < StandardError
attr_reader :status_code, :request_id
def initialize(status_code, message, request_id = nil)
super(message)
@status_code = status_code
@request_id = request_id
end
end
def send_email(payload, attempts = 3)
uri = URI('https://api.poststack.dev/emails')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.read_timeout = 10
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Bearer #{ENV.fetch('POSTSTACK_API_KEY')}"
req['Content-Type'] = 'application/json'
req.body = payload.to_json
attempts.times do |attempt|
res = http.request(req)
case res.code.to_i
when 200, 201
return JSON.parse(res.body)
when 429
sleep(res['retry-after']&.to_i || (2**attempt))
when 500..599
sleep(2**attempt)
else
raise PoststackError.new(res.code.to_i, res.body, res['x-request-id'])
end
end
raise 'send_email exhausted'
endFramework integrations
ActionMailer + SMTP
In `config/environments/production.rb`, set `config.action_mailer.delivery_method = :smtp` and `smtp_settings: { address: "smtp.poststack.dev", port: 587, user_name: "poststack", password: ENV.fetch("POSTSTACK_API_KEY"), authentication: :plain, tls: true }`. `tls: true` opens the connection with implicit TLS on port 587 (RFC 8314) — PostStack rejects STARTTLS, so do not use `enable_starttls_auto`. Every existing ActionMailer class — `UserMailer.welcome(user).deliver_later` — now goes through PostStack.
Pure Net::HTTP
For non-Rails Ruby apps (Sinatra, Hanami, Cuba, pure scripts), the example above is the entire integration. Wrap it in a service object and inject it into your routes.
Sidekiq / GoodJob workers
Push sends into a background job so the HTTP request returns quickly. The PostStack API key reads from `ENV.fetch` inside the worker — no need to pass it in job arguments.
Rails Mailer previews
Mailer previews under `test/mailers/previews` work the same way. Previews render the email but do not actually send, so you can iterate on templates without burning your sending quota.
Common pitfalls
Using STARTTLS instead of implicit TLS
PostStack’s relay uses implicit TLS on port 587 (RFC 8314) and rejects STARTTLS. Set `tls: true` in `smtp_settings` so the TLS handshake happens on connect — `enable_starttls_auto: true` will fail because the server never advertises STARTTLS.
Sending from `*@gmail.com`
Your `from` address must be on a verified PostStack domain. Sending from `example@gmail.com` is rejected. Verify your domain in the dashboard first.
Holding the HTTP connection open per-request
For high-throughput, share the `Net::HTTP` instance with `http.start { ... }` so the TLS connection is reused across sends. Spinning up a new TLS handshake per send adds 100–200 ms each.
Notes
- Uses the Ruby standard library — no gems required
- For Rails, you can also configure PostStack as an SMTP transport in config/environments/production.rb
FAQ
Do I need to install a gem?
No. Ruby’s standard library `Net::HTTP` is enough for REST calls, and Rails’s built-in ActionMailer handles SMTP. The PostStack-specific code is tiny.
Can I use ActionMailer?
Yes — configure SMTP as shown in the integrations section. Every existing `Mailer.deliver_later` call goes through PostStack with full tracking, webhooks, and deliverability.
How do I handle rate limits?
Inspect the `Retry-After` header on a 429 response and sleep for that many seconds before retrying. The example in the error-handling section above does this.
Related guides
Ready to send emails with Ruby on Rails?
Create a free account and get your API key in under a minute.