> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendbaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send emails with Ruby

> Learn how to send your first email from Ruby or Rails with the Sendbaze REST API.

## Prerequisites

* A Sendbaze [API key](https://docs.sendbaze.com/get-started/create-api-key.md)
* A [verified domain](https://docs.sendbaze.com/get-started/add-domain.md). A test key works without one, and so does the [shared test address](https://docs.sendbaze.com/get-started/test-without-a-domain.md) for emails to yourself.
* Ruby 3.1 or later

> [!NOTE]
>
> The examples use the standard library `net/http`, so nothing needs installing. An official gem is on the roadmap.

## Guide

**1. Set your API key**

```bash .env theme={"dark"}
SENDBAZE_API_KEY=sk_live_xxxxxxxx
```

**2. Send an email**

```ruby send.rb theme={"dark"}
require "net/http"
require "json"

uri = URI("https://api.sendbaze.com/v1/emails")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("SENDBAZE_API_KEY")}"
request["Content-Type"] = "application/json"
request.body = {
  from: "Yourshop <orders@yourshop.co.za>",
  to: "thandi@example.com",
  subject: "Your order #1042 has shipped",
  html: "<p>Tracking: <b>CG123456789ZA</b></p>"
}.to_json

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
body = JSON.parse(response.body)

if response.is_a?(Net::HTTPSuccess)
  puts body["id"] # em_01j9...
else
  warn "#{body.dig("error", "code")}: #{body.dig("error", "message")}"
end
```

**3. Try it**

Run `ruby send.rb` and open the dashboard **Logs**.

## Examples

### A small client

```ruby sendbaze.rb theme={"dark"}
require "net/http"
require "json"

class Sendbaze
  Error = Class.new(StandardError) do
    attr_reader :code, :fields
    def initialize(body)
      @code = body.dig("error", "code")
      @fields = body.dig("error", "fields")
      super(body.dig("error", "message"))
    end
  end

  def initialize(api_key: ENV.fetch("SENDBAZE_API_KEY"), base_url: "https://api.sendbaze.com")
    @api_key = api_key
    @base_url = base_url
  end

  def send_email(idempotency_key: nil, **email)
    request(:post, "/v1/emails", email, idempotency_key: idempotency_key)
  end

  def get_email(id)
    request(:get, "/v1/emails/#{id}")
  end

  private

  def request(method, path, body = nil, idempotency_key: nil)
    uri = URI(@base_url + path)
    req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
    req["Authorization"] = "Bearer #{@api_key}"
    req["Content-Type"] = "application/json"
    req["Idempotency-Key"] = idempotency_key if idempotency_key
    req.body = body.to_json if body
    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 30) { |http| http.request(req) }
    parsed = JSON.parse(res.body)
    raise Error.new(parsed) unless res.is_a?(Net::HTTPSuccess)
    parsed
  end
end
```

### Rails

Use a mailer-style service object from a job so a slow network never blocks a request.

```ruby app/jobs/send_receipt_job.rb theme={"dark"}
class SendReceiptJob < ApplicationJob
  queue_as :default

  def perform(order)
    Sendbaze.new.send_email(
      idempotency_key: "receipt-#{order.id}",
      from: "orders@yourshop.co.za",
      to: order.user.email,
      templateId: "tpl_receipt",
      variables: { name: order.user.first_name, order_id: order.id, total: order.total.format },
      tags: ["receipt"]
    )
  end
end
```

### Attach a file

```ruby theme={"dark"}
require "base64"

Sendbaze.new.send_email(
  from: "orders@yourshop.co.za",
  to: "thandi@example.com",
  subject: "Invoice 1042",
  html: "<p>Your invoice is attached.</p>",
  attachments: [
    { filename: "invoice-1042.pdf", contentType: "application/pdf", content: Base64.strict_encode64(File.binread("invoice-1042.pdf")) }
  ]
)
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.