unsent
unsent.dev
Get Started

Ruby

Official Unsent Ruby SDK for sending emails and managing contacts.

This guide shows how to install and use the official unsent Ruby SDK.

Installation

To get started, add the unsent gem to your application's Gemfile:

gem 'unsent'

Then execute the following command to install it:

bundle install

Initialize

Initialize the client with your API key.

require 'unsent'

client = Unsent::Client.new('un_xxx')

Send an email

Now you can send an email. The SDK methods return a tuple data, error. You should check if error is present to handle any issues.

Here is an example of sending a simple HTML email:

data, error = client.emails.send({
  to: 'user@example.com',
  from: 'no-reply@yourdomain.com',
  subject: 'Welcome',
  html: '<strong>Hello!</strong>'
})

if error
  puts "Error: #{error}"
else
  puts "Email sent! ID: #{data['id']}"
end

With attachments and scheduling

You can also send emails with attachments and schedule them for later delivery.

  • Attachments: Provide an array of attachments, where each attachment has a filename and content (Base64 encoded string).
  • Scheduling: Use the scheduledAt field with an ISO 8601 date string.
require 'time'

data, error = client.emails.create({
  to: 'user@example.com',
  from: 'no-reply@yourdomain.com',
  subject: 'Report',
  text: 'See attached.',
  attachments: [
    {
      filename: 'report.txt',
      content: 'SGVsbG8gd29ybGQ=' # Content must be Base64 encoded
    }
  ],
  scheduledAt: (Time.now + 600).iso8601 # Schedule for 10 minutes from now
})

Batch send

To send multiple emails efficiently in a single request, use the batch method.

emails = [
  {
    to: 'a@example.com',
    from: 'no-reply@yourdomain.com',
    subject: 'A',
    html: '<p>A</p>'
  },
  {
    to: 'b@example.com',
    from: 'no-reply@yourdomain.com',
    subject: 'B',
    html: '<p>B</p>'
  }
]

data, error = client.emails.batch(emails)

if data
  puts "Sent #{data['emails'].length} emails"
end

Idempotent Retries

To safely retry requests, you can pass an options hash with an idempotency_key.

# For single email
client.emails.send(email, { idempotency_key: 'unique-key-123' })

# For batch emails
client.emails.batch(emails, { idempotency_key: 'batch-unique-key-123' })

Retrieve and manage emails

You can retrieve details of sent emails, update scheduled emails, or cancel them.

Get an email

Fetch the status and details of a specific email using its ID:

email, error = client.emails.get('email_123')

if email
  puts "Email status: #{email['status']}"
end

Update schedule time

Change the scheduled delivery time for a pending email:

data, error = client.emails.update('email_123', {
  scheduledAt: (Time.now + 3600).iso8601 # Reschedule to 1 hour from now
})

Cancel a scheduled email

Cancel a scheduled email so it won't be sent:

data, error = client.emails.cancel('email_123')

if data
  puts 'Email cancelled successfully'
end

Contacts

Manage your contacts and organize them into contact books. All contact operations require a contact book ID.

Create a contact

Add a new contact to a specific contact book. You can include custom metadata.

data, error = client.contacts.create('book_123', {
  email: 'user@example.com',
  firstName: 'Jane',
  metadata: {
    plan: 'pro'
  }
})

Get a contact

Retrieve a contact's details:

contact, error = client.contacts.get('book_123', 'contact_456')

Update a contact

Update a contact's information:

data, error = client.contacts.update('book_123', 'contact_456', {
  firstName: 'John',
  metadata: {
    plan: 'enterprise'
  }
})

Upsert a contact

Use upsert to create a contact if they don't exist, or update them if they do.

data, error = client.contacts.upsert('book_123', 'contact_456', {
  email: 'user@example.com',
  firstName: 'Jane'
})

Delete a contact

Remove a contact from a book:

data, error = client.contacts.delete('book_123', 'contact_456')

Campaigns

Campaigns allow you to send emails to all contacts in a specific contact book.

Create a campaign

Create a new campaign by defining its content and the target contact book.

data, error = client.campaigns.create({
  name: 'Welcome Series',
  subject: 'Welcome!',
  html: '<p>Thanks for joining us!</p>',
  from: 'welcome@yourdomain.com',
  contactBookId: 'book_123'
})

Schedule a campaign

Schedule the campaign to be sent at a specific time.

data, error = client.campaigns.schedule('campaign_123', {
  scheduledAt: '2024-12-01T10:00:00Z'
})

Pause and resume campaigns

Control the delivery of your campaign.

# Pause
data, error = client.campaigns.pause('campaign_123')

# Resume
data, error = client.campaigns.resume('campaign_123')

Domains

Manage your sending domains.

List domains

Get a list of all domains and their statuses.

domains, error = client.domains.list

if domains
  domains.each do |domain|
    puts "Domain: #{domain['domain']}, Status: #{domain['status']}"
  end
end

Create a domain

Register a new domain for sending.

data, error = client.domains.create({
  domain: 'yourdomain.com'
})

Verify a domain

Check the verification status of a domain.

data, error = client.domains.verify(123)

if data
  puts "Verification status: #{data['status']}"
end

Error handling

The SDK supports two modes of error handling.

Raising Exceptions (Default)

By default, the SDK raises Unsent::HTTPError for non-2xx responses. This is useful for standard exception handling.

begin
  data, error = client.emails.get('email_123')
rescue Unsent::HTTPError => e
  puts "HTTP #{e.status_code}: #{e.error['message']}"
end

Returning Error Values

If you prefer to handle errors as return values without exceptions, pass raise_on_error: false when initializing the client.

client = Unsent::Client.new('un_xxx', raise_on_error: false)

data, error = client.emails.get('email_123')

if error
  puts "Error: #{error['message']}"
else
  puts "Success!"
end