Keplars Elixir SDK

Official Elixir SDK for the Keplars transactional email API.

Installation

Add keplars to your dependencies in mix.exs:

def deps do
[
{:keplars, "~> 1.10"}
]
end

Configuration

Set your API key via environment variable:

export KEPLARS_API_KEY="kms_your_key_id.live_your_secret"

Or pass it directly when creating the client.

API Key Types

TypeFormatUsed for
Regularkms_<id>.live_<secret>Email sending
Adminkms_<id>.adm_<secret>Contacts, audiences, automations, domains

Using Both Send and Admin Operations

Pass admin_key: as an option to Keplars.new/2 to use a single client for both:

{:ok, client} = Keplars.new("kms_<id>.live_<secret>", admin_key: "kms_<id>.adm_<secret>")
Keplars.Emails.send_instant(client, params) # uses api_key
Keplars.Audiences.list(client) # uses admin_key

If you only have an admin key, pass it directly:

{:ok, client} = Keplars.new("kms_<id>.adm_<secret>")

Usage

{:ok, client} = Keplars.new("kms_your_key_id.live_your_secret")
{:ok, resp} = Keplars.Emails.send(client, %{
to: "user@example.com",
from: "noreply@yourdomain.com",
subject: "Welcome!",
html: "<h1>Hi there!</h1>"
})

Priority-based sending

{:ok, _} = Keplars.Emails.send_instant(client, params)
{:ok, _} = Keplars.Emails.send_high(client, params)
{:ok, _} = Keplars.Emails.send_async(client, params)
{:ok, _} = Keplars.Emails.send_bulk(client, params)

Scheduling

{:ok, _} = Keplars.Emails.schedule(client, %{
to: "user@example.com",
from: "noreply@yourdomain.com",
subject: "Scheduled email",
html: "<h1>Hello</h1>",
scheduled_for: "2026-12-01T10:00:00Z"
})

Contacts

Use an admin key (kms_<id>.adm_<secret>) for contacts, audiences, automations, and domains.

{:ok, admin} = Keplars.new("kms_your_key_id.adm_your_secret")
{:ok, _} = Keplars.Contacts.add(admin, %{email: "user@example.com", name: "User"})
{:ok, _} = Keplars.Contacts.get(admin, "user@example.com")
{:ok, _} = Keplars.Contacts.list(admin, audience_id: "aud_123", page: 1, limit: 20)
{:ok, _} = Keplars.Contacts.update(admin, "user@example.com", %{name: "New Name"})
{:ok, _} = Keplars.Contacts.delete(admin, "user@example.com")

Audiences

{:ok, _} = Keplars.Audiences.create(admin, "My Audience", "Description")
{:ok, _} = Keplars.Audiences.list(admin)
{:ok, _} = Keplars.Audiences.get(admin, "aud_123")
{:ok, _} = Keplars.Audiences.delete(admin, "aud_123")

Automations

{:ok, _} = Keplars.Automations.list(admin)
{:ok, _} = Keplars.Automations.get(admin, "auto_123")
{:ok, _} = Keplars.Automations.enroll(admin, "auto_123", "user@example.com")
{:ok, _} = Keplars.Automations.unenroll(admin, "auto_123", "user@example.com")

Domains

{:ok, _} = Keplars.Domains.add(admin, "yourdomain.com")
{:ok, _} = Keplars.Domains.list(admin)
{:ok, _} = Keplars.Domains.get_status(admin, "dom_123")
{:ok, _} = Keplars.Domains.verify(admin, "dom_123")
{:ok, _} = Keplars.Domains.delete(admin, "dom_123")
{:ok, _} = Keplars.Domains.create_api_key(admin, %{domain_id: "dom_123", name: "My Key"})

Error Handling

All functions return {:ok, result} or {:error, %Keplars.Error{}}:

case Keplars.Emails.send(client, params) do
{:ok, %{data: data}} ->
IO.inspect(data)
{:error, %Keplars.Error{code: :authentication_error}} ->
IO.puts("Invalid API key")
{:error, %Keplars.Error{code: :rate_limit_exceeded, retry_after: seconds}} ->
IO.puts("Rate limited. Retry after #{seconds}s")
{:error, %Keplars.Error{message: msg}} ->
IO.puts("Error: #{msg}")
end

Error codes: :validation_error, :authentication_error, :authorization_error, :domain_not_verified, :rate_limit_exceeded, :not_found, :conflict, :internal_error, :network_error

Example Projects

License

MIT