Marketing Subscribers API
Overview
The Marketing Subscribers API provides comprehensive management of subscriber profiles within the Stack9 Customer Data Platform (CDP). This API enables you to create, manage, and track subscriber information, preferences, engagement history, and compliance requirements for marketing communications.
Resource Description
Marketing subscribers represent individual contacts in your customer database who have opted to receive marketing communications. Each subscriber profile consists of:
- Profile Information: Core demographic and contact details including name and email
- Subscription Status: Active/inactive status with reason tracking for compliance
- Segmentation: Assignment to audiences and lists for targeted marketing
- Preferences Management: Granular subscription type preferences with opt-in/opt-out tracking
- Custom Fields: Extensible additional fields for business-specific data
- Engagement History: Comprehensive tracking of all marketing interactions
- Compliance Tracking: GDPR/CCPA compliance with audit trail
Key Features
- Profile Management: Create and maintain comprehensive subscriber profiles
- Advanced Search: Powerful filtering and search capabilities across all subscriber attributes
- Preference Center: Self-service preference management with secure token-based access
- Engagement Analytics: Track opens, clicks, conversions and calculate engagement scores
- Custom Field Support: Store business-specific data with flexible field types
- Compliance Features: Built-in support for privacy regulations with audit trails
- List & Audience Management: Organize subscribers into targeted segments
- Suppression Management: Handle unsubscribes and compliance suppressions
Authentication
All endpoints require API key authentication:
X-API-Key: your-api-key-here
Subscriber Management
Create Subscriber
Create a new subscriber profile with initial segmentation and custom field data.
POST /api/subscribers
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | Subscriber's first name |
last_name | string | No | Subscriber's last name |
email | string | Yes | Valid email address (must be unique) |
active | boolean | Yes | Whether subscriber can receive marketing communications |
inactive_reason | string | No | Reason for inactive status (required if active=false) |
audiences | array | Yes | List of audience IDs the subscriber belongs to |
lists | array | Yes | List of marketing list IDs for segmentation |
additional_fields_data | object | No | Custom field values as key-value pairs |
Example Request
curl -X POST \
https://apis.app.stack9.co/api/subscribers \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"active": true,
"audiences": ["aud_retail_customers", "aud_newsletter"],
"lists": ["list_vip_members", "list_product_updates"],
"additional_fields_data": {
"customer_type": "premium",
"preferred_language": "en",
"date_of_birth": "1985-03-15",
"phone_number": "+1-555-0123",
"company": "Acme Corp",
"job_title": "Marketing Director"
}
}'
Example Response
{
"id": "sub_7k9mNp2QrT8x"
}
Error Responses
400 Bad Request
{
"message": "Invalid subscriber data",
"code": "INVALID_SUBSCRIBER",
"issues": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
409 Conflict
{
"message": "Subscriber with this email already exists",
"code": "DUPLICATE_EMAIL"
}
List Subscribers
Retrieve a paginated list of subscribers with advanced filtering and search capabilities.
POST /api/subscribers/list
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | Yes | Page number (1-based) |
limit | number | Yes | Items per page (max: 100) |
search | string | No | Search across name and email fields |
filters | object | Yes | Filter criteria object |
filters.first_name | object | No | Filter by first name |
filters.last_name | object | No | Filter by last name |
filters.email | object | No | Filter by email address |
filters.active | object | No | Filter by active status |
filters.audiences | object | No | Filter by audience membership |
filters.lists | object | No | Filter by list membership |
filters.created_at | object | No | Filter by creation date |
filters.updated_at | object | No | Filter by last update date |
Filter Operations
Each filter field supports the following operations:
eq: Equalsne: Not equalslike: Contains (partial match)nlike: Does not containgt: Greater thanlt: Less thangte: Greater than or equallte: Less than or equalin: In array of valuesnin: Not in array of valuesbetween: Between two valuesempty: Is empty/nullnempty: Is not empty/null
Example Request
curl -X POST \
https://apis.app.stack9.co/api/subscribers/list \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"page": 1,
"limit": 25,
"search": "john",
"filters": {
"active": {
"operation": "eq",
"value": true
},
"audiences": {
"operation": "in",
"value": ["aud_retail_customers"]
},
"created_at": {
"operation": "gte",
"value": "2024-01-01T00:00:00Z"
}
}
}'
Example Response
{
"results": [
{
"version": 2,
"created_at": "2024-03-15T10:30:00.123Z",
"updated_at": "2024-03-20T14:45:00.456Z",
"id": "sub_7k9mNp2QrT8x",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"active": true,
"audiences": ["aud_retail_customers", "aud_newsletter"],
"lists": ["list_vip_members", "list_product_updates"],
"subscription_preferences": [
{
"subscription_type_id": "stype_promotional",
"subscribed": true,
"subscribed_date": "2024-03-15T10:30:00.123Z",
"unsubscribed_date": null
},
{
"subscription_type_id": "stype_newsletter",
"subscribed": true,
"subscribed_date": "2024-03-15T10:30:00.123Z",
"unsubscribed_date": null
}
],
"additional_fields_data": {
"customer_type": "premium",
"preferred_language": "en",
"date_of_birth": "1985-03-15"
}
}
],
"total": 156,
"totalPages": 7
}
Get Subscriber by ID
Retrieve detailed information for a specific subscriber.
GET /api/subscribers/{id}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Subscriber's unique identifier |
Example Request
curl -X GET \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x \
-H 'X-API-Key: your-api-key-here'
Example Response
{
"version": 2,
"created_at": "2024-03-15T10:30:00.123Z",
"updated_at": "2024-03-20T14:45:00.456Z",
"id": "sub_7k9mNp2QrT8x",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"active": true,
"audiences": ["aud_retail_customers", "aud_newsletter"],
"lists": ["list_vip_members", "list_product_updates"],
"subscription_preferences": [
{
"subscription_type_id": "stype_promotional",
"subscribed": true,
"subscribed_date": "2024-03-15T10:30:00.123Z",
"unsubscribed_date": null
},
{
"subscription_type_id": "stype_newsletter",
"subscribed": false,
"subscribed_date": "2024-03-15T10:30:00.123Z",
"unsubscribed_date": "2024-03-18T09:00:00.000Z"
}
],
"additional_fields_data": {
"customer_type": "premium",
"preferred_language": "en",
"date_of_birth": "1985-03-15",
"lifetime_value": 15420.50,
"last_purchase_date": "2024-03-10",
"loyalty_tier": "gold"
}
}
Update Subscriber
Update an existing subscriber's profile, preferences, and segmentation.
PUT /api/subscribers/{id}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Subscriber's unique identifier (in path) |
first_name | string | Yes | Updated first name |
last_name | string | No | Updated last name |
email | string | Yes | Updated email address |
active | boolean | Yes | Updated active status |
inactive_reason | string | No | Reason if setting active=false |
audiences | array | Yes | Updated audience assignments |
lists | array | Yes | Updated list assignments |
additional_fields_data | object | No | Updated custom field values |
subscription_updates | array | No | Preference changes to apply |
Example Request
curl -X PUT \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@newcompany.com",
"active": true,
"audiences": ["aud_retail_customers", "aud_newsletter", "aud_loyalty_program"],
"lists": ["list_vip_members", "list_product_updates", "list_special_offers"],
"additional_fields_data": {
"customer_type": "enterprise",
"preferred_language": "en",
"company": "New Company Inc",
"loyalty_tier": "platinum"
},
"subscription_updates": [
{
"subscription_type_id": "stype_promotional",
"subscribe": false
},
{
"subscription_type_id": "stype_transactional",
"subscribe": true
}
]
}'
Example Response
{
"id": "sub_7k9mNp2QrT8x"
}
Delete Subscriber
Permanently delete a subscriber and all associated data. This action is irreversible and should be used for GDPR/CCPA compliance requests.
DELETE /api/subscribers/{id}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Subscriber's unique identifier |
Example Request
curl -X DELETE \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x \
-H 'X-API-Key: your-api-key-here'
Example Response
{
"id": "sub_7k9mNp2QrT8x"
}
Subscription Preferences
Get Subscriber Preferences
Retrieve a subscriber's marketing preferences using a secure token. This endpoint is designed for preference center pages.
GET /api/subscribers/preferences/{token}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Secure preference token (from email link) |
Example Request
curl -X GET \
https://apis.app.stack9.co/api/subscribers/preferences/eyJ0eXAiOiJKV1QiLCJhbGci... \
-H 'X-API-Key: your-api-key-here'
Example Response
{
"tenant": {
"id": "tenant_abc123",
"name": "Acme Corporation",
"brand_logo_url": "https://cdn.example.com/logo.png",
"brand_primary_color": "#FF5733"
},
"subscriber": {
"email": "john.doe@example.com",
"subscriptions": [
{
"subscription_type_id": "stype_promotional",
"subscribed": true
},
{
"subscription_type_id": "stype_newsletter",
"subscribed": true
},
{
"subscription_type_id": "stype_product_updates",
"subscribed": false
}
]
},
"available_subscription_types": [
{
"id": "stype_promotional",
"name": "Promotional Emails",
"description": "Special offers, sales, and exclusive deals"
},
{
"id": "stype_newsletter",
"name": "Monthly Newsletter",
"description": "Company news, tips, and industry insights"
},
{
"id": "stype_product_updates",
"name": "Product Updates",
"description": "New features and product announcements"
}
],
"referrer": {
"marketingEmailId": "memail_abc789",
"subscriptionTypeId": "stype_promotional"
}
}
Update Subscriber Preferences
Update marketing preferences via preference center. Supports granular opt-in/opt-out and global unsubscribe.
PUT /api/subscribers/preferences/{token}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Secure preference token (in path) |
subscription_updates | array | Yes | List of preference changes |
replace_all | boolean | Yes | Replace all preferences (true) or merge (false) |
subscriber_updates | object | No | Additional subscriber updates |
subscriber_updates.mark_inactive | boolean | No | Mark subscriber as globally unsubscribed |
subscriber_updates.inactive_reason | string | No | Reason for unsubscribe |
Example Request
curl -X PUT \
https://apis.app.stack9.co/api/subscribers/preferences/eyJ0eXAiOiJKV1QiLCJhbGci... \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"subscription_updates": [
{
"subscription_type_id": "stype_promotional",
"subscribe": false
},
{
"subscription_type_id": "stype_newsletter",
"subscribe": true
}
],
"replace_all": false,
"subscriber_updates": {
"mark_inactive": false
}
}'
Example Response
{
"success": true
}
Global Unsubscribe Example
curl -X PUT \
https://apis.app.stack9.co/api/subscribers/preferences/eyJ0eXAiOiJKV1QiLCJhbGci... \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"subscription_updates": [],
"replace_all": true,
"subscriber_updates": {
"mark_inactive": true,
"inactive_reason": "User requested global unsubscribe"
}
}'
Search and Analytics
Search Subscribers
Perform advanced search queries with aggregations for analytics and reporting.
POST /api/subscribers/search
Available Queries
Get Subscriber Count by List IDs
Count active subscribers in specific marketing lists.
curl -X POST \
https://apis.app.stack9.co/api/subscribers/search \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"payload": {
"queryName": "getSubscribersCountByListIds",
"vars": {
"listIds": ["list_vip_members", "list_product_updates"],
"activeSubscriptionTypeId": "stype_promotional"
}
}
}'
Response:
{
"subscribersCountByListId": {
"list_vip_members": 1250,
"list_product_updates": 3480
}
}
Get Subscriber Count by Audience IDs
Count active subscribers in audience segments.
curl -X POST \
https://apis.app.stack9.co/api/subscribers/search \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"payload": {
"queryName": "getSubscribersCountByAudienceIds",
"vars": {
"audienceIds": ["aud_retail_customers", "aud_newsletter"],
"activeSubscriptionTypeId": "stype_newsletter"
}
}
}'
Response:
{
"subscribersCountByAudienceId": {
"aud_retail_customers": 5670,
"aud_newsletter": 8920
}
}
Engagement History
Get Subscriber Engagements
Retrieve comprehensive engagement history for a subscriber across all campaigns.
POST /api/subscribers/{subscriberId}/engagements
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
subscriberId | string | Yes | Subscriber ID (in path) |
page | number | Yes | Page number (1-based) |
limit | number | Yes | Items per page |
filters | object | Yes | Filter criteria |
filters.campaignCode | string | No | Filter by specific campaign |
filters.marketingEmailId | string | No | Filter by specific email |
Example Request
curl -X POST \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x/engagements \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"page": 1,
"limit": 10,
"filters": {
"campaignCode": "SUMMER-SALE-2024"
}
}'
Example Response
{
"results": [
{
"subscriber_id": "sub_7k9mNp2QrT8x",
"campaign_code": "SUMMER-SALE-2024",
"marketing_email_id": "memail_xyz789",
"email_sent_at": "2024-06-15T10:00:00Z",
"email_delivered_at": "2024-06-15T10:00:15Z",
"delivery_status": "DELIVERED",
"first_opened_at": "2024-06-15T14:30:00Z",
"last_opened_at": "2024-06-16T09:15:00Z",
"open_count": 3,
"first_clicked_at": "2024-06-15T14:31:00Z",
"last_clicked_at": "2024-06-15T14:35:00Z",
"click_count": 5,
"unique_click_count": 2,
"clicked_links": [
{
"url": "https://shop.example.com/summer-sale",
"count": 3,
"first_clicked_at": "2024-06-15T14:31:00Z",
"last_clicked_at": "2024-06-15T14:35:00Z"
},
{
"url": "https://shop.example.com/products/beach-towel",
"count": 2,
"first_clicked_at": "2024-06-15T14:32:00Z",
"last_clicked_at": "2024-06-15T14:33:00Z"
}
],
"unsubscribed_at": null,
"first_page_view_at": "2024-06-15T14:31:30Z",
"last_page_view_at": "2024-06-15T14:45:00Z",
"page_view_count": 12,
"total_engagement_time_seconds": 840,
"first_purchase_at": "2024-06-15T14:42:00Z",
"last_purchase_at": "2024-06-15T14:42:00Z",
"purchase_count": 1,
"total_purchase_amount": 129.99,
"engagement_score": 8.5,
"updated_at": "2024-06-16T09:15:00Z",
"campaign_metadata": {
"send_date": "2024-06-15T10:00:00Z",
"subscription_type": "stype_promotional",
"subject_line": "Summer Sale - Up to 50% Off!"
}
}
],
"total": 24,
"totalPages": 3
}
Get Marketing Email Preview
Retrieve the HTML content of a marketing email for browser viewing. Used for "View in browser" links.
GET /api/subscribers/email/{token}/preview
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Secure email preview token |
Example Request
curl -X GET \
https://apis.app.stack9.co/api/subscribers/email/eyJ0eXAiOiJKV1QiLCJhbGci.../preview \
-H 'X-API-Key: your-api-key-here'
Example Response
{
"html_content": "<!DOCTYPE html><html><head><title>Summer Sale</title></head><body>...</body></html>"
}
Custom Fields Management
Custom fields allow you to store business-specific data for each subscriber. These fields are stored in the additional_fields_data object.
Supported Field Types
- String: Text values (names, codes, preferences)
- Number: Numeric values (scores, amounts, counts)
- Boolean: True/false flags
Common Custom Fields
| Field Name | Type | Description |
|---|---|---|
customer_type | string | Customer classification (e.g., retail, wholesale, enterprise) |
preferred_language | string | Language preference for communications |
date_of_birth | string | Birthday for targeted campaigns |
phone_number | string | Contact phone number |
company | string | Company affiliation |
job_title | string | Professional title |
lifetime_value | number | Total purchase value |
purchase_count | number | Number of purchases |
last_purchase_date | string | Most recent purchase |
loyalty_tier | string | Loyalty program level |
referral_source | string | How subscriber joined |
tags | string | Comma-separated tags |
Example: Using Custom Fields
# Create subscriber with custom fields
curl -X POST \
https://apis.app.stack9.co/api/subscribers \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "Sarah",
"email": "sarah@example.com",
"active": true,
"audiences": ["aud_all"],
"lists": ["list_customers"],
"additional_fields_data": {
"customer_type": "vip",
"lifetime_value": 25000,
"loyalty_tier": "platinum",
"preferred_language": "en",
"tags": "high-value,frequent-buyer,referrer"
}
}'
# Filter subscribers by custom field
curl -X POST \
https://apis.app.stack9.co/api/subscribers/list \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"page": 1,
"limit": 25,
"filters": {
"additional_fields_data.loyalty_tier": {
"operation": "eq",
"value": "platinum"
}
}
}'
Compliance and Data Protection
GDPR Compliance Features
- Right to Access: Use GET
/api/subscribers/{id}to retrieve all subscriber data - Right to Rectification: Use PUT
/api/subscribers/{id}to update incorrect data - Right to Erasure: Use DELETE
/api/subscribers/{id}for permanent deletion - Right to Restrict Processing: Set
active: falsewith appropriate reason - Consent Management: Track opt-in/opt-out through subscription preferences
CCPA Compliance Features
- Consumer Data Access: Full profile export via API
- Deletion Rights: Permanent deletion endpoint
- Opt-Out Rights: Preference management and suppression
- Audit Trail: Version tracking and timestamp records
Suppression List Management
Mark subscribers as inactive with specific reasons:
curl -X PUT \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "John",
"email": "john.doe@example.com",
"active": false,
"inactive_reason": "GDPR deletion request - Ticket #12345",
"audiences": [],
"lists": []
}'
Common inactive reasons:
"User unsubscribed""Hard bounce - Invalid email""Spam complaint""GDPR deletion request""CCPA opt-out""Data quality - Invalid contact"
Integration Patterns
Form Integration for Lead Capture
Example workflow for capturing leads from web forms:
// 1. Capture form submission
const formData = {
firstName: document.getElementById('first_name').value,
lastName: document.getElementById('last_name').value,
email: document.getElementById('email').value,
company: document.getElementById('company').value,
interests: getSelectedInterests()
};
// 2. Create subscriber via API
fetch('https://apis.app.stack9.co/api/subscribers', {
method: 'POST',
headers: {
'X-API-Key': 'your-api-key-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
first_name: formData.firstName,
last_name: formData.lastName,
email: formData.email,
active: true,
audiences: ['aud_leads'],
lists: mapInterestsToLists(formData.interests),
additional_fields_data: {
company: formData.company,
lead_source: 'website_form',
lead_date: new Date().toISOString()
}
})
});
Email Campaign Integration
Sync subscribers with email campaigns:
# 1. Get subscribers for a campaign segment
curl -X POST \
https://apis.app.stack9.co/api/subscribers/list \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"page": 1,
"limit": 100,
"filters": {
"lists": {
"operation": "in",
"value": ["list_summer_campaign"]
},
"active": {
"operation": "eq",
"value": true
}
}
}'
# 2. Track engagement after campaign send
curl -X POST \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x/engagements \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"page": 1,
"limit": 10,
"filters": {
"campaignCode": "SUMMER-2024"
}
}'
Journey Automation Integration
Trigger automated journeys based on subscriber attributes:
# Update subscriber to trigger journey
curl -X PUT \
https://apis.app.stack9.co/api/subscribers/sub_7k9mNp2QrT8x \
-H 'X-API-Key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "John",
"email": "john.doe@example.com",
"active": true,
"audiences": ["aud_retail_customers", "aud_abandoned_cart"],
"lists": ["list_vip_members"],
"additional_fields_data": {
"cart_value": 299.99,
"cart_abandoned_date": "2024-03-20T14:00:00Z",
"journey_trigger": "abandoned_cart"
}
}'
Best Practices
Data Quality
- Email Validation: Validate email format before creating subscribers
- Duplicate Prevention: Check for existing emails before creation
- Data Standardization: Normalize names and addresses
- Regular Cleanup: Remove or suppress invalid/bounced emails
- Field Consistency: Maintain consistent custom field naming
Compliance
- Explicit Consent: Always obtain clear opt-in consent
- Preference Granularity: Offer subscription type choices
- Easy Unsubscribe: Provide one-click unsubscribe options
- Data Retention: Implement retention policies
- Audit Trail: Track all preference changes with timestamps
- Suppression Lists: Maintain do-not-contact lists
Performance Optimization
- Batch Operations: Use search API for bulk analytics
- Pagination: Always paginate large result sets
- Field Selection: Request only needed fields
- Caching: Cache subscriber counts and segments
- Rate Limiting: Implement appropriate rate limiting
Segmentation Strategy
- Dynamic Segments: Use audiences for dynamic grouping
- Static Lists: Use lists for fixed campaigns
- Custom Attributes: Leverage custom fields for targeting
- Engagement Scoring: Track and utilize engagement scores
- Behavioral Triggers: Segment based on actions
Integration Guidelines
- Webhook Events: Subscribe to subscriber events
- Real-time Sync: Keep subscriber data synchronized
- Error Recovery: Implement retry logic for failures
- Data Mapping: Document field mappings clearly
- Testing: Test with sandbox environments first
Error Handling
Common Error Codes
| Code | Description | Resolution |
|---|---|---|
INVALID_SUBSCRIBER | Invalid subscriber data format | Check required fields and data types |
DUPLICATE_EMAIL | Email already exists | Use update instead of create |
SUBSCRIBER_NOT_FOUND | Subscriber ID not found | Verify subscriber ID exists |
INVALID_TOKEN | Invalid or expired token | Request new token |
RATE_LIMIT_EXCEEDED | Too many requests | Implement backoff strategy |
INVALID_FILTER | Invalid filter operation | Check filter syntax |
INVALID_PREFERENCE | Invalid subscription type | Verify subscription type exists |
Example Error Response
{
"message": "Validation failed",
"code": "VALIDATION_ERROR",
"issues": [
{
"field": "email",
"message": "Email format is invalid"
},
{
"field": "audiences",
"message": "At least one audience is required"
}
]
}
Migration Guide
Importing Existing Subscribers
When migrating from another system:
- Prepare Data: Export existing subscriber data
- Map Fields: Create field mapping document
- Validate Data: Clean and validate all records
- Batch Import: Use API to create subscribers in batches
- Verify Import: Check counts and sample records
- Set Preferences: Import subscription preferences
- Test Campaigns: Run test campaigns before go-live
Example Import Script
import requests
import csv
import time
API_KEY = 'your-api-key-here'
API_URL = 'https://apis.app.stack9.co/api/subscribers'
def import_subscribers(csv_file):
with open(csv_file, 'r') as file:
reader = csv.DictReader(file)
for row in reader:
subscriber_data = {
'first_name': row['first_name'],
'last_name': row.get('last_name', ''),
'email': row['email'],
'active': row.get('opt_in', 'true').lower() == 'true',
'audiences': row.get('segments', 'aud_all').split(','),
'lists': row.get('lists', 'list_default').split(','),
'additional_fields_data': {
'imported_from': 'legacy_system',
'import_date': datetime.now().isoformat(),
'original_id': row.get('id', '')
}
}
response = requests.post(
API_URL,
headers={'X-API-Key': API_KEY},
json=subscriber_data
)
if response.status_code != 200:
print(f"Failed to import {row['email']}: {response.text}")
else:
print(f"Imported {row['email']}")
time.sleep(0.1) # Rate limiting
import_subscribers('subscribers_export.csv')
Webhook Events
Stack9 can send webhook notifications for subscriber events:
Available Events
subscriber.created: New subscriber addedsubscriber.updated: Subscriber profile updatedsubscriber.deleted: Subscriber removedsubscriber.unsubscribed: Subscriber opted outsubscriber.resubscribed: Subscriber opted back insubscriber.bounced: Email bouncedsubscriber.complained: Spam complaint received
Event Payload Example
{
"event": "subscriber.updated",
"timestamp": "2024-03-20T14:45:00Z",
"data": {
"subscriber_id": "sub_7k9mNp2QrT8x",
"email": "john.doe@example.com",
"changes": {
"active": {
"old": true,
"new": false
},
"inactive_reason": {
"old": null,
"new": "User unsubscribed"
}
}
}
}
Support
For additional assistance with the Marketing Subscribers API:
- Documentation: https://docs.stack9.io/api/subscribers
- API Status: https://status.stack9.io
- Support Portal: https://support.stack9.io
- Email: api-support@stack9.io