Ruby SDK
The EmailList Ruby gem provides a simple client library and Rails integration for managing contacts automatically.
Installation
Add the gem to your Gemfile:
gem 'email_list_api'
Then run:
bundle install
Configuration
Configure the gem globally using an initializer (recommended for Rails apps):
# config/initializers/email_list_api.rb
EmailListApi.configure do |config|
config.api_key = ENV['EMAILLIST_API_KEY'] || Rails.application.credentials.dig(:emaillist, :api_key)
# api_version is optional (defaults to latest, based on gem version)
# config.api_version = 1
end
This sets a global default that will be used by all clients unless overridden. The configuration priority is:
- Explicit parameter (highest priority)
- Global configuration (
EmailListApi.configure) - Environment variable (
EMAILLIST_API_KEY)
Basic usage
Initialize the client and start making API calls. The base URL is automatically determined - no need to specify it!
require 'email_list_api'
# If configured globally, you can create a client without specifying the API key
client = EmailListApi::Client.new
# Or explicitly pass the API key (overrides global config)
client = EmailListApi::Client.new(
api_key: ENV['EMAILLIST_API_KEY']
)
# Optionally specify API version (defaults to latest)
client = EmailListApi::Client.new(
api_key: ENV['EMAILLIST_API_KEY'],
api_version: 1
)
# Create or update a project (idempotent)
project = client.upsert_project(name: 'My Project')
# Create a contact using project slug
contact = client.upsert_contact(
project: project[:data][:slug],
email: 'user@example.com',
first_name: 'John',
last_name: 'Doe'
)
Automatic URL detection: The gem automatically uses:
https://emaillist.dev/api/v1in production
You can override this by setting the EMAILLIST_API_URL environment variable.
Rails integration
The gem includes a Rails concern that automatically syncs your ActiveRecord models to EmailList contacts. This is perfect for syncing User models or any other models that represent contacts.
Basic setup
Include the concern in your model and configure it:
class User < ApplicationRecord
include EmailListApi::SyncsEmailListContact
syncs_email_list_contact project_slug: 'my-project'
end
Now, whenever a User is created or updated, it will automatically create or update the corresponding contact in EmailList.
Custom field mapping
If your model uses different field names, you can configure them:
class User < ApplicationRecord
include EmailListApi::SyncsEmailListContact
syncs_email_list_contact project_slug: 'my-project',
email_field: :email_address,
first_name_field: :given_name,
last_name_field: :family_name
end
Global configuration
The API key is always taken from the global configuration (set in the initializer). Create an initializer file:
# config/initializers/email_list_api.rb
EmailListApi.configure do |config|
config.api_key = ENV['EMAILLIST_API_KEY'] || Rails.application.credentials.dig(:emaillist, :api_key)
# api_version is optional (defaults to latest based on gem version)
# config.api_version = 1
end
Then in your models, you don't need to specify the API key:
class User < ApplicationRecord
include EmailListApi::SyncsEmailListContact
syncs_email_list_contact project_slug: 'my-project'
end
Custom API version
You can specify a custom API version per model (overrides global config):
class User < ApplicationRecord
include EmailListApi::SyncsEmailListContact
syncs_email_list_contact project_slug: 'my-project',
api_version: 1
end
If not specified:
- The API key is taken from global configuration or
EMAILLIST_API_KEYenvironment variable - The API version defaults to latest (based on gem version)
- The base URL is automatically determined (production or development)
Storing contact ID
Optionally, you can add a column to store the EmailList contact ID for faster lookups:
# Migration
class AddEmaillistContactIdToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :emaillist_contact_id, :integer
add_index :users, :emaillist_contact_id
end
end
The concern will automatically populate this field when contacts are created or updated.
Always sync option
By default, the concern only syncs when relevant fields (email, first_name, last_name) change.
If you want to sync on every save, regardless of field changes, use the always_sync option:
class User < ApplicationRecord
include EmailListApi::SyncsEmailListContact
syncs_email_list_contact project_slug: 'my-project',
always_sync: true
end
With always_sync: true, the contact will be synced to EmailList on every save,
even if no tracked fields changed. This is useful when you want to ensure the contact is always up-to-date.
How it works
The concern hooks into ActiveRecord callbacks:
- after_create: Creates a new contact in EmailList when the model is created
- after_update: Updates the contact in EmailList when relevant fields (email, first_name, last_name) change, or on every save if
always_sync: trueis set
The sync uses the upsert_contact API endpoint, which means:
- If a contact with the same email exists, it will be updated
- If no contact exists, a new one will be created
- You don't need to check if a contact exists before syncing
Error handling
By default, errors during sync are raised as exceptions so you're aware of any issues. This ensures your app fails loudly if there are problems with the EmailList API or gem bugs.
If you need to fail silently (e.g., during a known gem bug you're waiting to be fixed), you can configure error handling in the global configuration:
# config/initializers/email_list_api.rb
EmailListApi.configure do |config|
config.api_key = ENV['EMAILLIST_API_KEY']
# Fail silently - don't raise exceptions on sync errors
# Useful if there's a known gem bug you're waiting to be fixed
config.raise_on_sync_error = false
end
Note: When raise_on_sync_error: false, errors are still logged but won't break your model saves. This is useful for temporary workarounds during gem bugs, but we recommend keeping the default (true) to catch issues early.
Complete example
Here's a complete example of a User model with EmailList sync:
class User < ApplicationRecord
include EmailListApi::SyncsEmailListContact
# Configure EmailList sync
syncs_email_list_contact project_slug: ENV['EMAILLIST_PROJECT_SLUG'] || 'my-project',
email_field: :email,
first_name_field: :first_name,
last_name_field: :last_name
# Your model code here...
validates :email, presence: true
validates :email, uniqueness: true
end
# Usage:
user = User.create(
email: 'john@example.com',
first_name: 'John',
last_name: 'Doe'
)
# => Automatically creates contact in EmailList
user.update(first_name: 'Jane')
# => Automatically updates contact in EmailList
Using unsubscribe URLs in emails
When sending emails to your contacts, you need to include unsubscribe links to comply with email regulations and best practices. EmailList provides unsubscribe URLs that you can include in your email templates.
For a complete guide on how to get and use unsubscribe URLs in your emails (with examples in multiple languages), see the unsubscribe URLs guide.
API methods
The client provides methods for all API endpoints:
Projects
client.projects- List all projectsclient.project(id)- Get a projectclient.create_project(name:, description:)- Create a projectclient.upsert_project(name:, description:)- Create or update a projectclient.update_project(id, name:, description:)- Update a projectclient.delete_project(id)- Delete a project
Lists
client.lists(project:)- List all lists (project can be slug or ID)client.list(project:, id:)- Get a listclient.create_list(project:, name:, description:)- Create a listclient.upsert_list(project:, name:, description:)- Create or update a listclient.update_list(project:, id:, name:, description:)- Update a listclient.delete_list(project:, id:)- Delete a list
Contacts
client.contacts(project:, page:)- List contactsclient.contact(project:, id:)- Get a contactclient.create_contact(project:, email:, first_name:, last_name:)- Create a contactclient.update_contact(project:, id:, email:, first_name:, last_name:)- Update a contactclient.upsert_contact(project:, email:, first_name:, last_name:)- Create or update a contactclient.delete_contact(project:, id:)- Delete a contact
List memberships
client.list_contacts(project:, list_id:)- List contacts in a listclient.add_contacts_to_list(project:, list_id:, contacts:)- Add contacts to a listclient.add_contact_to_list(project:, list_id:, contact_id:)- Add a single contact to a listclient.remove_contact_from_list(project:, list_id:, contact_id:)- Remove a contact from a list
Bulk operations
client.bulk_create_contacts(project:, contacts:)- Create multiple contacts at once
Need help?
Check out the Contacts API documentation for more details on the API endpoints, or visit the API documentation index for all available endpoints.