Elixir
Send emails with the Unsent Elixir SDK
The Unsent Elixir SDK provides a simple and intuitive way to send transactional emails, manage contacts, campaigns, and domains from your Elixir applications.
Installation
Add unsent to your list of dependencies in mix.exs:
def deps do
[
{:unsent, "~> 1.0.2"}
]
endThen run mix deps.get to install the package.
Quick Start
# Initialize the client
client = Unsent.new("un_your_api_key")
# Send an email
{:ok, email} = Unsent.Emails.send(client, %{
to: "user@example.com",
from: "hello@yourdomain.com",
subject: "Welcome!",
html: "<p>Welcome to our service!</p>"
})Client Initialization
With API Key
client = Unsent.new("un_xxx")Using Environment Variable
Set UNSENT_API_KEY environment variable and initialize without passing the key:
client = Unsent.new()With Custom Options
client = Unsent.new("un_xxx",
base_url: "https://api.unsent.dev/v1",
raise_on_error: false # Return tuples instead of raising
)Sending Emails
Basic Email
{:ok, email} = Unsent.Emails.send(client, %{
to: "recipient@example.com",
from: "sender@yourdomain.com",
subject: "Hello from Elixir",
html: "<h1>Hello</h1><p>Email from Elixir SDK</p>",
text: "Hello! Email from Elixir SDK"
})Email with Attachments
Unsent.Emails.send(client, %{
to: "user@example.com",
from: "hello@company.com",
subject: "Document Attached",
html: "<p>Please find the document attached</p>",
attachments: [
%{
filename: "invoice.pdf",
content: "base64-encoded-content-here"
}
]
})Scheduled Email
# Schedule for 1 hour from now
scheduled_time = DateTime.utc_now() |> DateTime.add(3600, :second)
Unsent.Emails.send(client, %{
to: "user@example.com",
from: "hello@company.com",
subject: "Scheduled Email",
html: "<p>This email was scheduled</p>",
scheduledAt: DateTime.to_iso8601(scheduled_time)
})Batch Emails
Send up to 100 emails in a single API call:
emails = [
%{
to: "user1@example.com",
from: "hello@company.com",
subject: "Welcome User 1",
html: "<p>Welcome!</p>"
},
%{
to: "user2@example.com",
from: "hello@company.com",
subject: "Welcome User 2",
html: "<p>Welcome!</p>"
}
]
{:ok, result} = Unsent.Emails.batch(client, emails)Idempotent Requests
Use idempotency keys to safely retry requests:
Unsent.Emails.send(client, payload,
idempotency_key: "unique-request-id-123"
)Managing Emails
List Emails
# List all emails
{:ok, emails} = Unsent.Emails.list(client)
# With filters and pagination
Unsent.Emails.list(client,
page: 1,
limit: 50,
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-12-31T23:59:59Z",
domainId: "domain_id"
)
# Filter by multiple domains
Unsent.Emails.list(client, domainId: ["domain_1", "domain_2"])Get Email
{:ok, email} = Unsent.Emails.get(client, "email_id")Update Email
Unsent.Emails.update(client, "email_id", %{
scheduledAt: "2024-12-01T10:00:00Z"
})Cancel Email
Unsent.Emails.cancel(client, "email_id")Email Events
# Get bounced emails
{:ok, bounces} = Unsent.Emails.get_bounces(client, page: 1, limit: 20)
# Get spam complaints
{:ok, complaints} = Unsent.Emails.get_complaints(client)
# Get unsubscribes
{:ok, unsubscribes} = Unsent.Emails.get_unsubscribes(client)
# Get events for a specific email
{:ok, events} = Unsent.Emails.get_events(client, "email_id")
{:ok, events} = Unsent.Emails.get_events(client, "email_id", page: 1, limit: 20)Webhooks
Manage webhooks to receive real-time notifications about email events:
# List webhooks
{:ok, webhooks} = Unsent.Webhooks.list(client)
# Create webhook
{:ok, webhook} = Unsent.Webhooks.create(client, %{
url: "https://example.com/webhooks",
eventTypes: ["email.sent", "email.delivered", "email.bounced"]
})
# Get webhook
{:ok, webhook} = Unsent.Webhooks.get(client, webhook_id)
# Update webhook
Unsent.Webhooks.update(client, webhook_id, %{
url: "https://example.com/updated-webhook"
})
# Test webhook
Unsent.Webhooks.test(client, webhook_id)
# Delete webhook
Unsent.Webhooks.delete(client, webhook_id)Activity & Events
Activity Feed
Get recent activity for your account:
# Get activity feed
{:ok, activity} = Unsent.Activity.get(client)
# With pagination
Unsent.Activity.get(client, page: 1, limit: 50)Events
List all events across your account:
# List events
{:ok, events} = Unsent.Events.list(client)
# With filters
Unsent.Events.list(client,
page: 1,
limit: 100,
type: "email.delivered"
)Metrics & Stats
Metrics
Get detailed metrics for your account:
# Get metrics
{:ok, metrics} = Unsent.Metrics.get(client)
# With period filter
Unsent.Metrics.get(client, period: "month")Stats
Get aggregated statistics:
# Get stats
{:ok, stats} = Unsent.Stats.get(client)System & Teams
System Operations
Check API health and version:
# Health check
{:ok, health} = Unsent.System.health(client)
# Get API version
{:ok, version} = Unsent.System.version(client)Teams
Manage team information:
# Get current team
{:ok, team} = Unsent.Teams.get(client)
# List all teams
{:ok, teams} = Unsent.Teams.list(client)Contact Books & Contacts
Contact Books
# List contact books
{:ok, books} = Unsent.ContactBooks.list(client)
# Create contact book
{:ok, book} = Unsent.ContactBooks.create(client, %{
name: "Newsletter Subscribers"
})
# Get contact book
{:ok, book} = Unsent.ContactBooks.get(client, book_id)
# Update contact book
Unsent.ContactBooks.update(client, book_id, %{name: "Updated Name"})
# Delete contact book
Unsent.ContactBooks.delete(client, book_id)Contacts
# List contacts
{:ok, contacts} = Unsent.Contacts.list(client, book_id)
# With filters
Unsent.Contacts.list(client, book_id,
page: 1,
limit: 50,
emails: "user1@example.com,user2@example.com"
)
# Create contact
{:ok, contact} = Unsent.Contacts.create(client, book_id, %{
email: "user@example.com",
firstName: "John",
lastName: "Doe",
data: %{plan: "premium", signupDate: "2024-01-01"}
})
# Get contact
{:ok, contact} = Unsent.Contacts.get(client, book_id, contact_id)
# Update contact
Unsent.Contacts.update(client, book_id, contact_id, %{
firstName: "Jane"
})
# Upsert contact (create or update)
Unsent.Contacts.upsert(client, book_id, contact_id, %{
email: "user@example.com",
firstName: "John"
})
# Delete contact
Unsent.Contacts.delete(client, book_id, contact_id)Campaigns
# List campaigns
{:ok, campaigns} = Unsent.Campaigns.list(client)
# Create campaign (must include unsubscribe link)
{:ok, campaign} = Unsent.Campaigns.create(client, %{
name: "Welcome Series",
subject: "Welcome {{firstName}}!",
html: "<h1>Hi {{firstName}}</h1><p>Welcome to {{company}}</p><p><a href='{{unsent_unsubscribe_url}}'>Unsubscribe</a></p>",
from: "hello@company.com",
contactBookId: book_id
})
# Get campaign
{:ok, campaign} = Unsent.Campaigns.get(client, campaign_id)
# Schedule campaign
Unsent.Campaigns.schedule(client, campaign_id, %{
scheduledAt: "2024-12-01T10:00:00Z"
})
# Pause campaign
Unsent.Campaigns.pause(client, campaign_id)
# Resume campaign
Unsent.Campaigns.resume(client, campaign_id)Note: Campaign HTML must include the {{unsent_unsubscribe_url}} placeholder for compliance.
Domains
# List domains
{:ok, domains} = Unsent.Domains.list(client)
# Create domain
{:ok, domain} = Unsent.Domains.create(client, %{
name: "yourdomain.com",
region: "us-east-1"
})
# Verify domain
Unsent.Domains.verify(client, domain_id)
# Get domain
{:ok, domain} = Unsent.Domains.get(client, domain_id)
# Get domain analytics
{:ok, analytics} = Unsent.Domains.get_analytics(client, domain_id)
# Get domain stats
{:ok, stats} = Unsent.Domains.get_stats(client, domain_id)
# Delete domain
Unsent.Domains.delete(client, domain_id)Templates
# List templates
{:ok, templates} = Unsent.Templates.list(client)
# Create template
{:ok, template} = Unsent.Templates.create(client, %{
name: "Welcome Email",
subject: "Welcome {{name}}!",
html: "<h1>Hi {{name}}</h1><p>Welcome to {{company}}</p>"
})
# Get template
{:ok, template} = Unsent.Templates.get(client, template_id)
# Update template
Unsent.Templates.update(client, template_id, %{
subject: "Updated: Welcome {{name}}!"
})
# Delete template
Unsent.Templates.delete(client, template_id)
# Use template in email
Unsent.Emails.send(client, %{
to: "user@example.com",
from: "hello@company.com",
templateId: template_id,
templateData: %{name: "John", company: "Acme Inc"}
})Suppressions
Manage your suppression list to prevent emails from being sent to certain addresses:
# List all suppressions
{:ok, suppressions} = Unsent.Suppressions.list(client)
# With filters
Unsent.Suppressions.list(client,
page: 1,
limit: 50,
search: "example.com",
reason: "HARD_BOUNCE" # or "COMPLAINT", "MANUAL", "UNSUBSCRIBE"
)
# Add to suppression list
Unsent.Suppressions.add(client, %{
email: "blocked@example.com",
reason: "MANUAL"
})
# Remove from suppression list
Unsent.Suppressions.delete(client, "blocked@example.com")Analytics
Track your email performance and sender reputation:
# Get overall analytics
{:ok, analytics} = Unsent.Analytics.get(client)
# Get time series data
Unsent.Analytics.get_time_series(client, days: 30)
Unsent.Analytics.get_time_series(client, days: 7, domain: "yourdomain.com")
# Get reputation score
Unsent.Analytics.get_reputation(client)
Unsent.Analytics.get_reputation(client, domain: "yourdomain.com")Settings
# Get team settings
{:ok, settings} = Unsent.Settings.get(client)API Keys
# List API keys
{:ok, keys} = Unsent.ApiKeys.list(client)
# Create API key
{:ok, key} = Unsent.ApiKeys.create(client, %{
name: "Production Key",
permission: "FULL" # or "SENDING"
})
# Delete API key
Unsent.ApiKeys.delete(client, key_id)Provider Connections
Manage email provider connections (Amazon SES, SendGrid) for your team. Each connection stores encrypted credentials used by domains to route emails.
List Provider Connections
Get all configured provider connections:
{:ok, connections} = Unsent.ProviderConnections.list(client)
Enum.each(connections, fn conn ->
IO.puts("#{conn["name"]}: #{conn["provider"]}")
end)Create Provider Connection
Amazon SES
{:ok, connection} = Unsent.ProviderConnections.create(client, %{
provider: "ses",
name: "Production SES",
credentials: %{
accessKeyId: "AKIA...",
secretAccessKey: "...",
region: "us-east-1"
}
})
IO.puts("Provider connection created: #{connection["id"]}")SendGrid
{:ok, connection} = Unsent.ProviderConnections.create(client, %{
provider: "sendgrid",
name: "Marketing SendGrid",
credentials: %{
apiKey: "SG...."
}
})Delete Provider Connection
Remove a provider connection by ID:
{:ok, _} = Unsent.ProviderConnections.delete(client, "conn_abc123")Error Handling
Exceptions (Default)
By default, the SDK raises exceptions on errors:
try do
Unsent.Emails.send(client, invalid_payload)
rescue
e in Unsent.HTTPError ->
IO.puts("Error: #{e.error["message"]}")
IO.puts("Status code: #{e.status_code}")
endResult Tuples
Return {:ok, data} or {:error, reason} tuples instead:
client = Unsent.new("un_xxx", raise_on_error: false)
case Unsent.Emails.send(client, payload) do
{:ok, email} ->
IO.puts("Email sent successfully!")
{:error, error} ->
IO.puts("Failed to send: #{error["message"]}")
endAdvanced Features
Custom Headers
Unsent.Emails.send(client, payload,
headers: [
{"Idempotency-Key", "unique-id"},
{"X-Custom-Header", "value"}
]
)Base URL Override
client = Unsent.new("un_xxx", base_url: "https://custom-api.unsent.dev/v1")