Skip to main content

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

ParameterTypeRequiredDescription
first_namestringYesSubscriber's first name
last_namestringNoSubscriber's last name
emailstringYesValid email address (must be unique)
activebooleanYesWhether subscriber can receive marketing communications
inactive_reasonstringNoReason for inactive status (required if active=false)
audiencesarrayYesList of audience IDs the subscriber belongs to
listsarrayYesList of marketing list IDs for segmentation
additional_fields_dataobjectNoCustom 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

ParameterTypeRequiredDescription
pagenumberYesPage number (1-based)
limitnumberYesItems per page (max: 100)
searchstringNoSearch across name and email fields
filtersobjectYesFilter criteria object
filters.first_nameobjectNoFilter by first name
filters.last_nameobjectNoFilter by last name
filters.emailobjectNoFilter by email address
filters.activeobjectNoFilter by active status
filters.audiencesobjectNoFilter by audience membership
filters.listsobjectNoFilter by list membership
filters.created_atobjectNoFilter by creation date
filters.updated_atobjectNoFilter by last update date

Filter Operations

Each filter field supports the following operations:

  • eq: Equals
  • ne: Not equals
  • like: Contains (partial match)
  • nlike: Does not contain
  • gt: Greater than
  • lt: Less than
  • gte: Greater than or equal
  • lte: Less than or equal
  • in: In array of values
  • nin: Not in array of values
  • between: Between two values
  • empty: Is empty/null
  • nempty: 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

ParameterTypeRequiredDescription
idstringYesSubscriber'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

ParameterTypeRequiredDescription
idstringYesSubscriber's unique identifier (in path)
first_namestringYesUpdated first name
last_namestringNoUpdated last name
emailstringYesUpdated email address
activebooleanYesUpdated active status
inactive_reasonstringNoReason if setting active=false
audiencesarrayYesUpdated audience assignments
listsarrayYesUpdated list assignments
additional_fields_dataobjectNoUpdated custom field values
subscription_updatesarrayNoPreference 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

ParameterTypeRequiredDescription
idstringYesSubscriber'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

ParameterTypeRequiredDescription
tokenstringYesSecure 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

ParameterTypeRequiredDescription
tokenstringYesSecure preference token (in path)
subscription_updatesarrayYesList of preference changes
replace_allbooleanYesReplace all preferences (true) or merge (false)
subscriber_updatesobjectNoAdditional subscriber updates
subscriber_updates.mark_inactivebooleanNoMark subscriber as globally unsubscribed
subscriber_updates.inactive_reasonstringNoReason 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

ParameterTypeRequiredDescription
subscriberIdstringYesSubscriber ID (in path)
pagenumberYesPage number (1-based)
limitnumberYesItems per page
filtersobjectYesFilter criteria
filters.campaignCodestringNoFilter by specific campaign
filters.marketingEmailIdstringNoFilter 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

ParameterTypeRequiredDescription
tokenstringYesSecure 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 NameTypeDescription
customer_typestringCustomer classification (e.g., retail, wholesale, enterprise)
preferred_languagestringLanguage preference for communications
date_of_birthstringBirthday for targeted campaigns
phone_numberstringContact phone number
companystringCompany affiliation
job_titlestringProfessional title
lifetime_valuenumberTotal purchase value
purchase_countnumberNumber of purchases
last_purchase_datestringMost recent purchase
loyalty_tierstringLoyalty program level
referral_sourcestringHow subscriber joined
tagsstringComma-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

  1. Right to Access: Use GET /api/subscribers/{id} to retrieve all subscriber data
  2. Right to Rectification: Use PUT /api/subscribers/{id} to update incorrect data
  3. Right to Erasure: Use DELETE /api/subscribers/{id} for permanent deletion
  4. Right to Restrict Processing: Set active: false with appropriate reason
  5. Consent Management: Track opt-in/opt-out through subscription preferences

CCPA Compliance Features

  1. Consumer Data Access: Full profile export via API
  2. Deletion Rights: Permanent deletion endpoint
  3. Opt-Out Rights: Preference management and suppression
  4. 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

  1. Email Validation: Validate email format before creating subscribers
  2. Duplicate Prevention: Check for existing emails before creation
  3. Data Standardization: Normalize names and addresses
  4. Regular Cleanup: Remove or suppress invalid/bounced emails
  5. Field Consistency: Maintain consistent custom field naming

Compliance

  1. Explicit Consent: Always obtain clear opt-in consent
  2. Preference Granularity: Offer subscription type choices
  3. Easy Unsubscribe: Provide one-click unsubscribe options
  4. Data Retention: Implement retention policies
  5. Audit Trail: Track all preference changes with timestamps
  6. Suppression Lists: Maintain do-not-contact lists

Performance Optimization

  1. Batch Operations: Use search API for bulk analytics
  2. Pagination: Always paginate large result sets
  3. Field Selection: Request only needed fields
  4. Caching: Cache subscriber counts and segments
  5. Rate Limiting: Implement appropriate rate limiting

Segmentation Strategy

  1. Dynamic Segments: Use audiences for dynamic grouping
  2. Static Lists: Use lists for fixed campaigns
  3. Custom Attributes: Leverage custom fields for targeting
  4. Engagement Scoring: Track and utilize engagement scores
  5. Behavioral Triggers: Segment based on actions

Integration Guidelines

  1. Webhook Events: Subscribe to subscriber events
  2. Real-time Sync: Keep subscriber data synchronized
  3. Error Recovery: Implement retry logic for failures
  4. Data Mapping: Document field mappings clearly
  5. Testing: Test with sandbox environments first

Error Handling

Common Error Codes

CodeDescriptionResolution
INVALID_SUBSCRIBERInvalid subscriber data formatCheck required fields and data types
DUPLICATE_EMAILEmail already existsUse update instead of create
SUBSCRIBER_NOT_FOUNDSubscriber ID not foundVerify subscriber ID exists
INVALID_TOKENInvalid or expired tokenRequest new token
RATE_LIMIT_EXCEEDEDToo many requestsImplement backoff strategy
INVALID_FILTERInvalid filter operationCheck filter syntax
INVALID_PREFERENCEInvalid subscription typeVerify 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:

  1. Prepare Data: Export existing subscriber data
  2. Map Fields: Create field mapping document
  3. Validate Data: Clean and validate all records
  4. Batch Import: Use API to create subscribers in batches
  5. Verify Import: Check counts and sample records
  6. Set Preferences: Import subscription preferences
  7. 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 added
  • subscriber.updated: Subscriber profile updated
  • subscriber.deleted: Subscriber removed
  • subscriber.unsubscribed: Subscriber opted out
  • subscriber.resubscribed: Subscriber opted back in
  • subscriber.bounced: Email bounced
  • subscriber.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: