Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.letterby.com/llms.txt

Use this file to discover all available pages before exploring further.

Introduction to Audiences

Audiences allow you to segment your contacts into targeted groups for personalized campaigns, analytics, and engagement strategies. Letterby supports two types of audiences:
  • Manual Audiences: Manually curated contact lists
  • Smart Audiences: Dynamic segments that automatically update based on filter criteria

Getting Started

Prerequisites

Before working with audiences, ensure you have:
  • A valid API key with access to your Letterby account
  • At least one project (list) with contacts
  • Understanding of your contact data structure
All audience endpoints require authentication via the apiKey header.

Creating Audiences

Manual Audiences

Manual audiences are perfect for hand-picked segments like VIP customers or beta testers.
curl --request POST \
  --url https://letterby.com/api/v4/audiences \
  --header 'Content-Type: application/json' \
  --header 'apiKey: YOUR_API_KEY' \
  --data '{
    "name": "VIP Customers",
    "listId": "your_list_id",
    "mode": "manual"
  }'

Smart Audiences

Smart audiences automatically include contacts based on filter criteria. They update in real-time as your contact data changes.
curl --request POST \
  --url https://letterby.com/api/v4/audiences \
  --header 'Content-Type: application/json' \
  --header 'apiKey: YOUR_API_KEY' \
  --data '{
    "name": "High-Value Contacts",
    "listId": "your_list_id",
    "mode": "smart",
    "filters": "{\"points\": {\"gte\": 100}, \"isVerified\": true}"
  }'

Advanced Filtering for Smart Audiences

Smart audiences use Prisma-compatible where clauses, allowing for complex filtering logic.

Basic Filtering Examples

By Points Range

{
	"filters": "{\"points\": {\"gte\": 50, \"lte\": 200}}"
}

By Email Domain

{
	"filters": "{\"email\": {\"contains\": \"@gmail.com\"}}"
}

By Verification Status

{
	"filters": "{\"isVerified\": true, \"unsubscribed\": false}"
}

Complex Filtering with AND/OR Logic

Gmail Users with High Points

{
	"filters": "{\"AND\": [{\"email\": {\"contains\": \"@gmail.com\"}}, {\"points\": {\"gt\": 100}}]}"
}

Multiple Conditions with OR

{
	"filters": "{\"OR\": [{\"points\": {\"gte\": 200}}, {\"referrals\": {\"gte\": 5}}]}"
}

Complex Nested Logic

{
	"filters": "{\"AND\": [{\"isVerified\": true}, {\"OR\": [{\"points\": {\"gte\": 100}}, {\"company\": {\"in\": [\"Google\", \"Apple\", \"Microsoft\"]}}]}]}"
}

Available Filter Fields

FieldTypeDescriptionExample
emailStringContact’s email address{"contains": "@company.com"}
firstNameStringFirst name{"startsWith": "John"}
lastNameStringLast name{"endsWith": "Smith"}
pointsNumberPoints accumulated{"gte": 100}
referralsNumberNumber of referrals{"gt": 5}
isVerifiedBooleanVerification statustrue
unsubscribedBooleanSubscription statusfalse
companyStringCompany name{"in": ["Tech Corp", "StartupXYZ"]}
countryStringCountry{"equals": "United States"}
cityStringCity{"contains": "New York"}
createdAtDateRegistration date{"gte": "2024-01-01T00:00:00Z"}

String Operators

  • equals: Exact match
  • contains: Partial match (case-insensitive)
  • startsWith: Starts with text
  • endsWith: Ends with text
  • in: Matches any value in array
  • notIn: Doesn’t match any value in array

Number Operators

  • equals: Exact value
  • gt: Greater than
  • gte: Greater than or equal
  • lt: Less than
  • lte: Less than or equal
  • in: Matches any value in array

Managing Audiences

Listing All Audiences

Retrieve all audiences for a specific list:
curl --request GET \
  --url 'https://letterby.com/api/v4/audiences?listId=your_list_id' \
  --header 'apiKey: YOUR_API_KEY'

Retrieving a Specific Audience

Get detailed information about a single audience:
curl --request GET \
  --url https://letterby.com/api/v4/audiences/audience_id \
  --header 'apiKey: YOUR_API_KEY'

Updating Audiences

Modify audience properties including name, filters, and mode:
curl --request PATCH \
  --url https://letterby.com/api/v4/audiences/audience_id \
  --header 'Content-Type: application/json' \
  --header 'apiKey: YOUR_API_KEY' \
  --data '{
    "name": "Updated Audience Name",
    "filters": "{\"points\": {\"gte\": 150}}"
  }'

Practical Use Cases

1. Customer Lifecycle Segmentation

// New subscribers (less than 30 days)
const newSubscribers = {
	name: 'New Subscribers',
	mode: 'smart',
	filters: JSON.stringify({
		createdAt: {
			gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
		},
	}),
}

// Engaged users (high points)
const engagedUsers = {
	name: 'Engaged Users',
	mode: 'smart',
	filters: JSON.stringify({
		points: { gte: 50 },
		isVerified: true,
	}),
}

// At-risk users (no recent activity)
const atRiskUsers = {
	name: 'At-Risk Users',
	mode: 'smart',
	filters: JSON.stringify({
		points: { lt: 10 },
		createdAt: {
			lte: new Date(Date.now() - 60 * 24 * 60 * 60 * 1000).toISOString(),
		},
	}),
}

2. Geographic Targeting

// US-based enterprise contacts
const usEnterprise = {
	name: 'US Enterprise',
	mode: 'smart',
	filters: JSON.stringify({
		AND: [
			{ country: { equals: 'United States' } },
			{ company: { not: null } },
			{ points: { gte: 25 } },
		],
	}),
}

3. Referral Champions

// Top referrers
const referralChampions = {
	name: 'Referral Champions',
	mode: 'smart',
	filters: JSON.stringify({
		referrals: { gte: 3 },
	}),
}

Best Practices

1. Naming Conventions

  • Use descriptive names: “High-Value Gmail Users” vs “Audience 1”
  • Include criteria in the name when helpful
  • Use consistent naming patterns across your organization

2. Filter Optimization

  • Start with simple filters and gradually add complexity
  • Test filters with small datasets first
  • Use specific date ranges to avoid overly large audiences

3. Regular Maintenance

  • Review audience performance regularly
  • Update filter criteria based on changing business needs
  • Archive unused audiences to keep your workspace clean

4. Testing Smart Audiences

// Test your filters before creating the audience
const testFilters = {
	points: { gte: 100 },
	isVerified: true,
}

// First, test with the contacts endpoint
const testResponse = await fetch(
	`https://letterby.com/api/v4/contacts?listId=your_list_id&points=100&isVerified=true`,
	{
		headers: { apiKey: 'YOUR_API_KEY' },
	},
)

const testResults = await testResponse.json()
console.log(`Filter would match ${testResults.data.pagination.total} contacts`)

Error Handling

Common Errors and Solutions

Invalid Filters Format

{
	"error": "Invalid filters format. Must be a valid Prisma where clause for Sub model"
}
Solution: Ensure your filters follow Prisma where clause syntax and are valid JSON.

Missing Required Fields

{
	"error": "Name and listId are required"
}
Solution: Always include name and listId when creating audiences.

Filters Required for Smart Mode

{
	"error": "Filters are required for smart mode"
}
Solution: Smart audiences must include a filters parameter. For detailed endpoint documentation, see:

Next Steps

Once you’ve mastered audiences, explore:
  • Using audiences in email campaigns
  • Analyzing audience engagement metrics
  • Building automated workflows based on audience membership
  • Integrating audiences with your CRM or marketing tools
Smart audiences update automatically, so contacts will move in and out based on their current data. This makes them perfect for dynamic marketing campaigns and automated workflows.