Contacts
The Contacts API allows you to manage contacts within contact books for your email campaigns.
Base URL
https://api.unsent.dev/v1/contactBooks/{contactBookId}/contactsOverview
The Contacts API provides comprehensive endpoints for managing individual contacts within your contact books. You can create, retrieve, update, upsert, and delete contacts, as well as query them using various filters.
Features
Create contacts
Add new contacts with email, name, and custom properties
List & filter contacts
Retrieve contacts with pagination and filters by email or ID
Upsert contacts
Create or update contacts in a single operation
Update contacts
Modify contact information and properties
Search by email/ID
Filter contacts by specific emails or contact IDs
Delete contacts
Remove contacts from your contact books
API Endpoints
List Contacts
GET /contactBooks/{contactBookId}/contacts
Retrieve multiple contacts from a contact book with optional filtering and pagination.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number for pagination (default: 1) |
limit | number | No | Number of contacts per page (default: 5000) |
emails | string | No | Comma-separated list of email addresses to filter |
ids | string | No | Comma-separated list of contact IDs to filter |
Example Request
# Get all contacts with pagination
curl -X GET "https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts?page=1&limit=50" \
-H "Authorization: Bearer your-api-key"
# Filter by specific emails
curl -X GET "https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts?emails=john@example.com,jane@example.com" \
-H "Authorization: Bearer your-api-key"
# Filter by contact IDs
curl -X GET "https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts?ids=contact_1,contact_2" \
-H "Authorization: Bearer your-api-key"Response
[
{
"id": "cuiwqdj74rygf74",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"subscribed": true,
"properties": {
"company": "Acme Corp",
"phone": "+1-555-0123"
},
"contactBookId": "book_123",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
]Get Single Contact
GET /contactBooks/{contactBookId}/contacts/{contactId}
Retrieve a specific contact by ID.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactBookId | string | Yes | The contact book ID |
contactId | string | Yes | The contact ID to retrieve |
Example Request
curl -X GET https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts/contact_abc123 \
-H "Authorization: Bearer your-api-key"Response
{
"id": "contact_abc123",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"subscribed": true,
"properties": {
"company": "Acme Corp",
"role": "Manager"
},
"contactBookId": "cuiwqdj74rygf74",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:45:00Z"
}Create Contact
POST /contactBooks/{contactBookId}/contacts
Add a new contact to a contact book.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Contact's email address |
firstName | string | No | Contact's first name |
lastName | string | No | Contact's last name |
subscribed | boolean | No | Subscription status (default: true) |
properties | object | No | Custom key-value pairs |
Example Request
curl -X POST https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"subscribed": true,
"properties": {
"company": "Acme Corp",
"phone": "+1-555-0123",
"source": "newsletter_signup"
}
}'Response
{
"contactId": "contact_new123"
}Update Contact
PATCH /contactBooks/{contactBookId}/contacts/{contactId}
Update an existing contact's information. Only the provided fields will be updated.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
firstName | string | No | Updated first name |
lastName | string | No | Updated last name |
subscribed | boolean | No | Updated subscription status |
properties | object | No | Updated custom properties |
Note: Email addresses cannot be updated via PATCH. Use the upsert endpoint instead.
Example Request
curl -X PATCH https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts/contact_abc123 \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Johnathan",
"subscribed": false,
"properties": {
"last_purchase": "2024-01-15",
"tier": "premium"
}
}'Response
{
"contactId": "contact_abc123"
}Upsert Contact
PUT /contactBooks/{contactBookId}/contacts/{contactId}
Create a new contact or update an existing one based on the email address. This is useful when you're not sure if the contact already exists.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Contact's email address |
firstName | string | No | Contact's first name |
lastName | string | No | Contact's last name |
subscribed | boolean | No | Subscription status |
properties | object | No | Custom key-value pairs |
Example Request
curl -X PUT https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts/any_id \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.smith@example.com",
"firstName": "Jane",
"lastName": "Smith",
"subscribed": true,
"properties": {
"source": "website_signup",
"plan": "premium"
}
}'Response
{
"contactId": "contact_xyz789"
}Delete Contact
DELETE /contactBooks/{contactBookId}/contacts/{contactId}
Permanently remove a contact from a contact book.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactBookId | string | Yes | The contact book ID |
contactId | string | Yes | The contact ID to delete |
Example Request
curl -X DELETE https://api.unsent.dev/v1/contactBooks/cuiwqdj74rygf74/contacts/contact_abc123 \
-H "Authorization: Bearer your-api-key"Response
{
"success": true
}Interactive API Reference
Data Model
Contact Object
{
id: string; // Unique contact identifier
email: string; // Contact's email address
firstName?: string | null; // Contact's first name
lastName?: string | null; // Contact's last name
subscribed: boolean; // Subscription status (default: true)
properties: Record<string, string>; // Custom properties
contactBookId: string; // Parent contact book ID
createdAt: string; // ISO 8601 timestamp
updatedAt: string; // ISO 8601 timestamp
}Custom Properties
Custom properties allow you to store additional information about contacts. All property values must be strings.
{
"properties": {
"company": "Acme Corp",
"phone": "+1-555-0123",
"country": "United States",
"signup_date": "2024-01-01",
"customer_tier": "premium",
"purchase_count": "15",
"referral_source": "google_ads"
}
}Filtering & Pagination
Pagination
Use page and limit parameters to paginate through large contact lists:
# First page with 100 contacts
GET /contactBooks/{id}/contacts?page=1&limit=100
# Second page
GET /contactBooks/{id}/contacts?page=2&limit=100Filtering by Email
Retrieve specific contacts by email addresses:
GET /contactBooks/{id}/contacts?emails=user1@example.com,user2@example.comFiltering by ID
Retrieve specific contacts by their IDs:
GET /contactBooks/{id}/contacts?ids=contact_1,contact_2,contact_3Combining Filters
You can combine pagination with filters:
GET /contactBooks/{id}/contacts?emails=user@example.com&page=1&limit=10Subscription Management
Opt-in Status
- subscribed: true - Contact can receive emails (default)
- subscribed: false - Contact will not receive emails
Unsubscribing Contacts
curl -X PATCH https://api.unsent.dev/v1/contactBooks/{contactBookId}/contacts/{contactId} \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"subscribed": false}'Common Use Cases
Newsletter Subscribers
{
"email": "subscriber@example.com",
"firstName": "Jane",
"subscribed": true,
"properties": {
"source": "website_form",
"interests": "technology,business",
"signup_date": "2024-01-15"
}
}E-commerce Customers
{
"email": "customer@example.com",
"firstName": "John",
"lastName": "Doe",
"subscribed": true,
"properties": {
"customer_id": "CUST_12345",
"tier": "premium",
"last_purchase": "2024-01-10",
"total_orders": "15",
"lifetime_value": "2500"
}
}Event Attendees
{
"email": "attendee@example.com",
"firstName": "Sarah",
"subscribed": true,
"properties": {
"event_id": "EVENT_2024",
"ticket_type": "VIP",
"dietary_restrictions": "vegetarian",
"checked_in": "true"
}
}SaaS Users
{
"email": "user@startup.com",
"firstName": "Alex",
"lastName": "Johnson",
"subscribed": true,
"properties": {
"user_id": "usr_abc123",
"plan": "pro",
"signup_date": "2024-01-01",
"trial_ends": "2024-01-15",
"feature_usage": "high"
}
}Best Practices
- Validate email addresses before adding contacts to ensure data quality
- Use meaningful property names for consistency across your contact base
- Implement proper error handling for duplicate emails and validation errors
- Use upsert operations when you're unsure if a contact exists
- Respect privacy regulations (GDPR, CCPA, etc.) and obtain proper consent
- Regularly clean contact data to remove bounced or invalid emails
- Use pagination when retrieving large contact lists to improve performance
- Store timestamps as strings in custom properties for consistency
Error Handling
Common Errors
| Status Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Invalid email format or missing required fields |
| 404 | Not Found | Contact or contact book not found |
| 409 | Conflict | Contact with this email already exists (POST only) |
| 500 | Internal Server Error | Server-side error occurred |
Example Error Response
{
"error": {
"code": "NOT_FOUND",
"message": "Contact not found"
}
}Rate Limits
- Contact operations: 500 requests per minute
- Bulk contact retrieval: 100 requests per minute
- Contact book ID must belong to your team