Email Fast Get a sandbox key
Docs

Quickstart: Ruby

Net::HTTP and JSON from the standard library are enough — no gem to add before your first send.

Facts verified 2026-07-17 — corrections: hello@emailfast.dev

1. Send

The API is plain JSON over HTTPS with bearer auth. Ruby 3's Net::HTTP.post takes a headers hash directly. (A generated Ruby SDK covers the same surface — see the docs — but the raw calls hide nothing.)

require "net/http"
require "json"
require "uri"

API_KEY = ENV.fetch("EMAILFAST_API_KEY") # ef_sandbox_… works everywhere

res = Net::HTTP.post(
  URI("https://api.emailfast.dev/v1/emails"),
  {
    to: "ada@example.com",
    subject: "Welcome to the ledger",
    html: "<h1>Hi {{name}}</h1><p>Your account is ready.</p>",
    data: { name: "Ada" },
    idempotency_key: "welcome-ada-1" # retry-safe: same key can never double-send
  }.to_json,
  "Authorization" => "Bearer #{API_KEY}",
  "Content-Type" => "application/json"
)

msg = JSON.parse(res.body)
puts "#{msg["id"]} #{msg["status"]}" # msg_… queued

a 202 from the API means the send is committed to a durable, partitioned outbox before we answer — a crash can't lose it, and a retry with the same idempotency key can't double-send. That is what idempotency_key buys you: wrap this call in retryable, Sidekiq's retry, or a bare begin/rescue/retry — a timeout after the server committed the send still can't produce a duplicate.

2. Watch it happen

timeline = JSON.parse(
  Net::HTTP.get(
    URI("https://api.emailfast.dev/v1/messages/#{msg["id"]}"),
    { "Authorization" => "Bearer #{API_KEY}" }
  )
)

timeline["events"].each { |e| puts e["type"] } # admitted → rendered → (sandbox-)delivered …

With a sandbox key the message lands in your hosted capture inbox — same pipeline, nothing sent: sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves.

Rails note

Nothing here needs Rails, but if you are in one: put the two calls in a job, keep the idempotency_key derived from your own record id ("welcome-user-#{user.id}"), and job retries become harmless by construction.

Next

See it for yourself

Sandbox keys run the real pipeline dry — real validation, real events, a hosted inbox, no email sent. Early access is onboarding now.