Send email from Ruby
Five steps: check your Ruby, create a test key, send to the sandbox, read the log, then verify a domain so you can send to anyone. Using Rails? The Rails quickstart puts the same steps in a service object.
1. Install
No SDK needed. The API is plain JSON over HTTPS, and net/http and json ship with Ruby.
ruby --version # 3.0 or newer; net/http and json ship with Ruby2. Create an API key
Sign in, open API keys in the dashboard and create a test key. It starts with av_test_. Export it so the script can read it:
export AVELTO_API_KEY=av_test_...3. Send your first email
Every request carries the key as a bearer token. The small api helper below sends JSON, parses the response and aborts with the code and message from the error envelope on any non-2xx status.
# send.rbrequire "net/http"require "json"API = "https://api.avelto.dev"HEADERS = { "Authorization" => "Bearer #{ENV.fetch("AVELTO_API_KEY")}", "Content-Type" => "application/json",}def api(method, path, body = nil) uri = URI("#{API}#{path}") req = Net::HTTP.const_get(method).new(uri, HEADERS) req.body = JSON.generate(body) if body res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) } data = res.body.to_s.empty? ? nil : JSON.parse(res.body) unless res.is_a?(Net::HTTPSuccess) abort "#{res.code} #{data["error"]["code"]}: #{data["error"]["message"]}" end dataendemail = api(:Post, "/v1/emails", { from: "you@sandbox.avelto.dev", to: "delivered@sandbox.avelto.dev", subject: "Hello from Avelto", text: "It works.",})puts email["id"] # "9c1f4a52-6f6e-4b8f-9b8e-2e1a5c7d3f10"ruby send.rbThe API answers 201 Created with the email id:
HTTP/1.1 201 CreatedContent-Type: application/json{ "id": "9c1f4a52-6f6e-4b8f-9b8e-2e1a5c7d3f10" }4. Check the log
Fetch the email by id with the same helper. status moves from queued to sent to delivered, and events records each step: email.queued, email.sent, email.delivered.
email = api(:Get, "/v1/emails/#{email["id"]}")puts email["status"] # "queued", then "sent", then "delivered"email["events"].each { |e| puts "#{e["type"]} #{e["occurred_at"]}" }{ "id": "9c1f4a52-6f6e-4b8f-9b8e-2e1a5c7d3f10", "mode": "test", "from": "you@sandbox.avelto.dev", "to": ["delivered@sandbox.avelto.dev"], "subject": "Hello from Avelto", "status": "delivered", "events": [ { "id": "e1f0c3a4-8b2d-4c6e-9a1f-5d7b3e2c8a90", "type": "email.queued", "payload": {}, "occurred_at": "2026-09-17T10:12:04.000Z" }, { "id": "a7c2e9d1-3f4b-4a8e-b6c0-2d9e1f7b5c34", "type": "email.sent", "payload": { "test": true, "ses_message_id": "test-9c1f4a52-6f6e-4b8f-9b8e-2e1a5c7d3f10" }, "occurred_at": "2026-09-17T10:12:06.000Z" }, { "id": "c4b8d2f6-7e1a-4d3c-8f9b-6a2e0c5d1b78", "type": "email.delivered", "payload": { "test": true, "recipients": ["delivered@sandbox.avelto.dev"] }, "occurred_at": "2026-09-17T10:12:06.000Z" } ]}5. Verify a domain
Add a domain, publish the DNS records it prints (an ownership TXT, an SPF TXT and a DMARC TXT, then three DKIM CNAMEs once the ownership record is found), then poll GET /v1/domains/:id until status is verified. The GET re-checks DNS on every call. Use a subdomain such as mail.acme.com.
# verify_domain.rb (reuse the api helper from send.rb)def show(domain) domain["dns_records"].each do |r| puts "#{r["type"]}\t#{r["name"]}\t#{r["value"]}\t(#{r["purpose"]})" endenddomain = api(:Post, "/v1/domains", { name: "mail.acme.com" })show(domain) # the ownership record first, with SPF and DMARC# Publish the records, then poll. GET re-checks DNS on every call.# Once the ownership record is found, the DKIM records appear: publish those too.while domain["status"] == "pending" sleep 30 latest = api(:Get, "/v1/domains/#{domain["id"]}") show(latest) if latest["ownership_verified"] && !domain["ownership_verified"] domain = latestendputs domain["status"] # "verified" or "failed"ruby verify_domain.rbOnce the domain is verified, switch AVELTO_API_KEY to a live key (av_live_) and change from to an address on it, such as hello@mail.acme.com. Nothing else changes.
Next
- Send email: every field, attachments, tags, scheduling and idempotency.
- Webhooks: get events pushed to your app.
- Test mode: test keys, the sandbox sender and the simulator addresses.