Official Ruby SDK for the Unsent API - Send transactional emails with ease.
- Unsent API key
- Verified domain
- Ruby 3.0 or higher
Add this line to your application's Gemfile:
gem 'unsent'And then execute:
bundle installOr install it yourself as:
gem install unsentrequire 'unsent'
client = Unsent::Client.new('un_xxx')You can also set your API key using environment variables:
# Set UNSENT_API_KEY in your environment
# Then initialize without passing the key
client = Unsent::Client.newdata, 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']}"
endrequire '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=' # base64
}
],
scheduledAt: (Time.now + 600).iso8601 # 10 minutes from now
})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)
puts "Sent #{data['emails'].length} emails" if dataTo prevent duplicate emails when retrying failed requests, you can provide an idempotency key.
data, error = client.emails.send({
to: 'user@example.com',
from: 'no-reply@yourdomain.com',
subject: 'Welcome',
html: '<strong>Hello!</strong>'
}, {
idempotency_key: 'unique-key-123'
})email, error = client.emails.get('email_123')
puts "Email status: #{email['status']}" if emaildata, error = client.emails.update('email_123', {
scheduledAt: (Time.now + 3600).iso8601 # 1 hour from now
})data, error = client.emails.cancel('email_123')
puts 'Email cancelled successfully' if datadata, error = client.contacts.create('book_123', {
email: 'user@example.com',
firstName: 'Jane',
metadata: {
plan: 'pro'
}
})contact, error = client.contacts.get('book_123', 'contact_456')data, error = client.contacts.update('book_123', 'contact_456', {
firstName: 'John',
metadata: {
plan: 'enterprise'
}
})data, error = client.contacts.upsert('book_123', 'contact_456', {
email: 'user@example.com',
firstName: 'Jane'
})data, error = client.contacts.delete('book_123', 'contact_456')data, error = client.campaigns.create({
name: 'Welcome Series',
subject: 'Welcome!',
html: '<p>Thanks for joining us!</p>',
from: 'welcome@yourdomain.com',
contactBookId: 'book_123'
})data, error = client.campaigns.schedule('campaign_123', {
scheduledAt: '2024-12-01T10:00:00Z'
})# Pause
data, error = client.campaigns.pause('campaign_123')
# Resume
data, error = client.campaigns.resume('campaign_123')domains, error = client.domains.list
domains.each do |domain|
puts "Domain: #{domain['domain']}, Status: #{domain['status']}"
end if domainsdata, error = client.domains.create({
domain: 'yourdomain.com'
})data, error = client.domains.verify(123)
puts "Verification status: #{data['status']}" if dataBy default, the SDK raises Unsent::HTTPError for non-2xx responses:
begin
data, error = client.emails.get('email_123')
rescue Unsent::HTTPError => e
puts "HTTP #{e.status_code}: #{e.error['message']}"
endTo handle errors as return values instead:
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!"
endRetrieve a paginated list of emails with optional filters:
data, error = client.emails.list(
page: 1,
limit: 10,
startDate: '2024-01-01',
endDate: '2024-01-31',
domainId: 'domain_123'
)
# Support for multiple domain IDs
data, error = client.emails.list(domainId: ['domain_1', 'domain_2'])# Get complaints
data, error = client.emails.get_complaints(page: 1, limit: 10)
# Get bounces
data, error = client.emails.get_bounces(page: 1, limit: 10)
# Get unsubscribes
data, error = client.emails.get_unsubscribes(page: 1, limit: 10)
# Get events for a specific email
events, error = client.emails.get_events('email_123', page: 1, limit: 10)
if events
events['data'].each do |event|
puts "Event: #{event['type']} at #{event['timestamp']}"
end
endManage your sending domains and retrieve domain-specific analytics.
# Get analytics for a specific domain
data, error = client.domains.get_analytics('domain_123', days: 30)
puts "Total sent: #{data['sent']}, Delivered: #{data['delivered']}" if data
# Get analytics with custom date range
data, error = client.domains.get_analytics(
'domain_123',
startDate: '2024-01-01',
endDate: '2024-01-31'
)
# Get domain statistics
stats, error = client.domains.get_stats('domain_123', days: 7)
puts "Bounce rate: #{stats['bounceRate']}%" if stats
# Get stats with custom date range
stats, error = client.domains.get_stats(
'domain_123',
startDate: '2024-01-01',
endDate: '2024-01-15'
)domains, error = client.domains.list
domains.each do |domain|
puts "Domain: #{domain['domain']}, Status: #{domain['status']}"
end if domainsdata, error = client.contact_books.create(
name: 'Newsletter Subscribers',
emoji: '📧'
)books, error = client.contact_books.list
books.each { |book| puts book['name'] }book, error = client.contact_books.get('book_123')data, error = client.contact_books.update('book_123', name: 'Updated Name')data, error = client.contact_books.delete('book_123')data, error = client.contacts.list('book_123',
page: 1,
limit: 10,
search: 'john@example.com'
)campaigns, error = client.campaigns.listGet insights into your email sending performance.
data, error = client.analytics.get
puts "Sent: #{data['sent']}, Delivered: #{data['delivered']}"data, error = client.analytics.get_time_series(
days: 30,
domain: 'yourdomain.com'
)data, error = client.analytics.get_reputation(domain: 'yourdomain.com')
puts "Reputation Score: #{data['score']}"Manage reusable email templates.
data, error = client.templates.create(
name: 'Welcome Email',
subject: 'Welcome to {{companyName}}!',
html: '<h1>Welcome {{firstName}}!</h1>'
)templates, error = client.templates.listtemplate, error = client.templates.get('template_123')data, error = client.templates.update('template_123',
subject: 'Updated Subject'
)data, error = client.templates.delete('template_123')Manage your email suppression list.
data, error = client.suppressions.list(
page: 1,
limit: 10,
reason: 'MANUAL',
search: 'user@'
)data, error = client.suppressions.add(
email: 'blocked@example.com',
reason: 'MANUAL'
)data, error = client.suppressions.delete('blocked@example.com')Manage your API keys programmatically.
keys, error = client.api_keys.listdata, error = client.api_keys.create(
name: 'Production Key',
permission: 'SENDING'
)
puts "New key: #{data['key']}"data, error = client.api_keys.delete('key_123')Note: Webhooks are currently a future feature and are documented here for reference.
Configure webhooks to receive real-time notifications.
webhooks, error = client.webhooks.listdata, error = client.webhooks.create(
url: 'https://yourdomain.com/webhooks',
events: ['email.sent', 'email.delivered', 'email.bounced']
)data, error = client.webhooks.update('webhook_123',
url: 'https://yourdomain.com/updated-webhook'
)data, error = client.webhooks.delete('webhook_123')Retrieve account settings.
settings, error = client.settings.getAfter checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests.
Bug reports and pull requests are welcome on GitHub at https://github.com/souravsspace/unsent-ruby.
The gem is available as open source under the terms of the MIT License.