Contacts
Contacts represent individual subscribers. Contacts belong to a project and can be members of multiple lists.
Unsubscribe URLs
All contact responses include an unsubscribe_urls hash mapping list IDs to unsubscribe URLs.
When fetching contacts from a specific list endpoint, use the unsubscribe_url field (singular) for that list.
Include these URLs in your email templates to provide recipients with unsubscribe functionality.
/api/v1/projects/:project_id/contacts
Retrieve all contacts for a project. Results are paginated.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| project_id | integer | Yes | The project ID |
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Items per page (default: 25) |
Success response (200)
client.contacts(project_id: 1, page: 1)
# => {
# "data" => [
# {
# "id" => 1,
# "project_id" => 1,
# "email" => "user@example.com",
# "first_name" => "John",
# "last_name" => "Doe",
# "full_name" => "John Doe",
# "unsubscribed_at" => nil,
# "active" => true,
# "lists_count" => 2,
# "unsubscribe_urls" => {
# 1 => "https://emaillist.dev/unsubscribe/abc123token...",
# 2 => "https://emaillist.dev/unsubscribe/def456token..."
# },
# "created_at" => "2024-01-01T00:00:00Z",
# "updated_at" => "2024-01-01T00:00:00Z"
# }
# ],
# "meta" => {
# "page" => 1,
# "per_page" => 25,
# "total" => 100,
# "total_pages" => 4
# }
# }
/api/v1/projects/:project_id/contacts/:id
Retrieve a specific contact by ID.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| project_id | integer | Yes | The project ID |
| id | integer | Yes | The contact ID |
Success response (200)
client.contact(project_id: 1, id: 1)
/api/v1/projects/:project_id/contacts
Create a new contact in a project.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| project_id | integer | Yes | The project ID |
Request body
client.create_contact(
project_id: 1,
email: 'user@example.com',
first_name: 'John',
last_name: 'Doe'
)
Success response (201)
{
"data" => {
"id" => 1,
"project_id" => 1,
"email" => "user@example.com",
"first_name" => "John",
"last_name" => "Doe",
"full_name" => "John Doe",
"unsubscribed_at" => nil,
"active" => true,
"lists_count" => 0,
"unsubscribe_urls" => {},
"created_at" => "2024-01-01T00:00:00Z",
"updated_at" => "2024-01-01T00:00:00Z"
}
}
Error responses
Status: 422 - validation_error
{
"error" => {
"code" => "validation_error",
"message" => "Validation failed",
"details" => {
"email" => ["can't be blank", "is invalid"]
}
}
}
/api/v1/projects/:project_id/contacts/:id
Update an existing contact.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| project_id | integer | Yes | The project ID |
| id | integer | Yes | The contact ID |
Request body
client.update_contact(
project_id: 1,
id: 1,
email: 'newemail@example.com',
first_name: 'Jane'
)
Success response (200)
{
"data" => {
"id" => 1,
"project_id" => 1,
"email" => "newemail@example.com",
"first_name" => "Jane",
"last_name" => "Doe",
"full_name" => "Jane Doe",
"unsubscribed_at" => nil,
"active" => true,
"lists_count" => 2,
"unsubscribe_urls" => {
1 => "https://emaillist.dev/unsubscribe/abc123token...",
2 => "https://emaillist.dev/unsubscribe/def456token..."
},
"created_at" => "2024-01-01T00:00:00Z",
"updated_at" => "2024-01-02T00:00:00Z"
}
}
/api/v1/projects/:project_id/contacts/upsert
Create or update a contact by email. If a contact with the given email exists, it will be updated (returns 200 OK). Otherwise, a new contact will be created (returns 201 Created). This is useful for syncing contacts without needing to check if they exist first.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| project_id | integer | Yes | The project ID |
Request body
client.upsert_contact(
project_id: 1,
email: 'user@example.com',
first_name: 'John',
last_name: 'Doe'
)
Success response (201)
# Returns 201 Created for new contacts, 200 OK for updates
client.upsert_contact(
project_id: 1,
email: 'user@example.com',
first_name: 'John',
last_name: 'Doe'
)
# => {
# "data" => {
# "id" => 1,
# "project_id" => 1,
# "email" => "user@example.com",
# "first_name" => "John",
# "last_name" => "Doe",
# "full_name" => "John Doe",
# "unsubscribed_at" => nil,
# "active" => true,
# "lists_count" => 0,
# "unsubscribe_urls" => {},
# "created_at" => "2024-01-01T00:00:00Z",
# "updated_at" => "2024-01-01T00:00:00Z"
# }
# }
Error responses
Status: 422 - validation_error
{
"error" => {
"code" => "validation_error",
"message" => "Email is required"
}
}
/api/v1/projects/:project_id/contacts/:id
Delete a contact. This will also remove the contact from all lists.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| project_id | integer | Yes | The project ID |
| id | integer | Yes | The contact ID |
Success response (204)
# No content