Ruby SDK

The official Ruby SDK for Veil Mail with idiomatic Ruby patterns.

  • Exception-based error handling
  • Keyword arguments for clean method calls
  • Constant-time HMAC webhook verification
  • Zero external dependencies (stdlib only)
  • Ruby 3.0+ compatible

Installation

gem install veilmail

# Or add to your Gemfile:
gem "veilmail"

Quick Start

send.rb
require "veilmail"

client = VeilMail::Client.new("veil_live_xxxxx")

email = client.emails.send(
  from: "hello@yourdomain.com",
  to: "user@example.com",
  subject: "Hello from Ruby!",
  html: "<h1>Welcome!</h1>"
)

puts email["id"]     # email_xxxxx
puts email["status"] # queued

Resources

The client exposes the same resources as the Node.js SDK:

ResourceDescription
client.emailsSend, batch send, list, get, cancel, update emails
client.domainsCreate, verify, update, list, delete domains
client.templatesCreate, update, preview, list, delete templates
client.audiencesManage audiences and subscribers
client.campaignsCreate, schedule, send, pause, resume, cancel campaigns
client.webhooksManage webhook endpoints, test, rotate secrets
client.topicsManage subscription topics and preferences
client.propertiesManage contact property definitions and values

Subscriber Management

subscribers.rb
subs = client.audiences.subscribers("audience_xxxxx")

# Add a subscriber
subscriber = subs.add(
  email: "user@example.com",
  first_name: "Alice",
  last_name: "Smith",
  consent_type: "express"
)

# List subscribers
result = subs.list(status: "active", limit: 50)
result["data"].each { |sub| puts sub["email"] }

# Import from CSV
result = subs.import(csv_data: "email,firstName\nuser@example.com,Bob")
puts "Created: #{result['created']}, Skipped: #{result['skipped']}"

# Export as CSV
csv = subs.export(status: "active")

Error Handling

errors.rb
begin
  client.emails.send(
    from: "hello@yourdomain.com",
    to: "user@example.com",
    subject: "Hello",
    html: "<p>Hi!</p>"
  )
rescue VeilMail::RateLimitError => e
  puts "Rate limited. Retry after #{e.retry_after}s"
rescue VeilMail::PiiDetectedError => e
  puts "PII detected: #{e.pii_types}"
rescue VeilMail::ValidationError => e
  puts "Validation error: #{e.message}"
rescue VeilMail::AuthenticationError
  puts "Invalid API key"
rescue VeilMail::Error => e
  puts "API error: #{e.message} (code: #{e.code})"
end

Webhook Verification

Use the built-in utility to verify webhook signatures in Rails:

webhooks_controller.rb
class WebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def veilmail
    body = request.raw_post
    signature = request.headers["X-Signature-Hash"]

    unless VeilMail::Webhook.verify_signature(body, signature, ENV["WEBHOOK_SECRET"])
      head :unauthorized
      return
    end

    event = JSON.parse(body)
    case event["type"]
    when "email.delivered"
      # Handle delivery
    when "email.bounced"
      # Handle bounce
    end

    head :ok
  end
end

Required Scopes

The Ruby SDK uses the same API scopes as the Authentication system. See the Node.js SDK documentation for the full scope reference.