Every dashboard action is an MCP tool your agent can call.Read the docs

Send emails with Rails

Transactional and marketing email from a Rails service object or ActiveJob. One HTTP call, and retries never send twice.

✓Free to start. Unlimited contacts on every tier.

Server quickstart
Rails

One request, complete trace

Request

POST /api/v1/emails

Authorization: Bearer aem_…

Idempotency-Key: welcome-8f21

{ "to": "[email protected]", "template": "welcome" }

202 Accepted

{ "id": "msg_7ca31", "status": "queued" }

RuntimeServer process
RequestPOST /api/v1/emails
Result202 · queued
Credentials stay server-side

[ 01 / 05 ]Quickstart

How do I send email from Rails?

Create a key, keep it on the server, and call one endpoint from a service object or ActiveJob.

  1. Get an API key

    Open Settings → API & MCP and create a key with the Send + manage permission (the default). It starts with aem_ and is shown once.

  2. Store it as a server-side environment variable

    Set AEM_KEY in the environment of your web and job processes. The code reads it with ENV.fetch, so a missing key fails loudly.

    Environment
    AEM_KEY=aem_…
  3. Send the email

    Net::HTTP.post sends the request, and anything but a 2xx raises. When ActiveJob retries, the same Idempotency-Key keeps it to one email.

    send_welcome.rb
    uri = URI('https://sendandretain.com/api/v1/emails')
    headers = {
      'Authorization' => "Bearer #{ENV.fetch('AEM_KEY')}",
      'Content-Type' => 'application/json',
      'Idempotency-Key' => "welcome-#{user.id}"
    }
    body = { to: user.email, template: 'welcome' }.to_json
    response = Net::HTTP.post(uri, body, headers)
    raise "Send failed: #{response.code} #{response.body}" unless response.is_a?(Net::HTTPSuccess)
  4. Check the response

    A 202 means queued, not delivered. Keep the id, then follow delivery in the message log or through a signed webhook.

    202 Accepted
    { "id": "msg_7ca31", "status": "queued" }

[ 02 / 05 ]Where it goes

Where should email code live in your Rails app?

Service objects and jobs

A service object keeps the send visible. ActiveJob hands retries to Sidekiq, Solid Queue, or your chosen backend.

Events after commit

Send events after commit, not from model callbacks that may run inside a transaction.

A raw body for webhooks

A controller action with skip_forgery_protection reads request.raw_post.

[ 03 / 05 ]Marketing email

Can I send marketing emails from Rails too?

Yes. Send an event from the same service object when a user signs up, starts a trial, or goes quiet, and an automation sends the right email. Automations start paused, and every email goes to one person: no newsletter blasts.

  • Transactional and marketing email share one contact record and one unsubscribe list.
  • Unsubscribes, bounces, and complaints are suppressed for you before every send.
  • Templates are react.email components; published versions never change under you.

[ 04 / 05 ]Example prompts

What can you ask your coding agent to do in Rails?

Claude Code, Cursor, and Codex can do these over the Send & Retain MCP server, with your repo open. Automations they build stay paused until you turn them on.

  • Welcome email

    “Add a welcome email to our Rails signup using Send & Retain, with an idempotency key.”

  • ActiveJob

    “Move our receipt email out of the model callback into an ActiveJob that calls Send & Retain after commit.”

  • Webhook

    “Add a Rails controller that verifies Send & Retain delivery webhooks and marks bounced users.”

  • Trial automation

    “Send a trial_started event from our Rails app and build a paused trial-conversion automation for it.”

Questions people ask us

Send your first email from Rails today.

Create a key, paste the code into a service object or ActiveJob, and watch the email land in the message log.