# Send email with Ruby

> Send email from Ruby with Email Fast: a complete Net::HTTP example against the REST API, with a sandbox key, an idempotency key, and error handling.

Canonical: https://emailfast.dev/send-email-with/ruby

Ruby's `Net::HTTP` handles the Email Fast API without a single gem: one JSON POST,
one bearer header, one status check. If you'd rather have a typed client, the
[Ruby SDK quickstart](/docs/quickstart-ruby) covers it; on Rails, the
[Rails guide](/send-email-with/rails) wraps this call in a service object and a job.

```ruby
# send.rb — Ruby 3.x, stdlib only
require "json"
require "net/http"
require "uri"

uri = URI("https://api.emailfast.dev/v1/emails")

req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("EMAILFAST_API_KEY")}" # ef_sandbox_... while testing
req["Content-Type"] = "application/json"
req.body = JSON.generate(
  to: "ada@example.com",
  subject: "Welcome",
  html: "<h1>Hi {{name}}</h1>",
  data: { name: "Ada" },
  idempotency_key: "welcome-ada-1" # a retry replays, never re-sends
)

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 10) do |http|
  http.request(req)
end

raise "Send rejected (#{res.code}): #{res.body}" unless res.is_a?(Net::HTTPSuccess)

result = JSON.parse(res.body)
puts "#{result["id"]} #{result["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.

## Gotchas

- `Net::HTTP` does not raise on 4xx/5xx — it hands you the error response and moves on. Check `Net::HTTPSuccess` yourself; the JSON body names the exact rejection.
- `use_ssl: true` is not inferred from the URL. Forget it and the request talks plaintext to port 443 and fails confusingly.
- `ENV.fetch` (not `ENV[]`) fails loudly at boot when the key is missing — the failure you want.
- Sending many? Keep the `Net::HTTP.start` block open and reuse the connection, or POST up to 500 messages to `/v1/emails/batch` in one call.

## Next

- [Ruby SDK quickstart](/docs/quickstart-ruby) — the typed client
- [The email API](/features/email-api) — batch, scheduling, message timelines
- [Sending from Rails](/send-email-with/rails)
- [All docs](/docs)
