Registration & Integration Workflows Guide
Complete guide to external subscription methods for your CRM platform
Last Updated: October 27, 2025
Table of Contents
- Overview
- Public Subscription API
- Website Form Integration
- Email Signature Links
- Social Media Integration
- QR Code Registration
- LinkedIn Integration (Planned)
- Unsubscribe Mechanism
- CASL Compliance
- Troubleshooting
Overview
This CRM platform provides multiple methods for external users to subscribe to your distribution lists without requiring CRM login credentials. All methods are CASL compliant and include automatic consent tracking.
Available Registration Methods
| Method | Status | Use Case | Difficulty |
|---|---|---|---|
| Website Forms | ✅ Live | Website footer, landing pages | Easy |
| Email Signature Links | ✅ Live | Professional email signatures | Easy |
| Social Media Links | ✅ Live | Social media profiles | Easy |
| QR Codes | ✅ Live | Print materials, business cards | Easy |
| Public API | ✅ Live | Custom integrations | Medium |
| LinkedIn Integration | ⏳ Planned | Import connections | Medium |
Benefits
- No login required for subscribers
- Instant list membership
- Automatic duplicate prevention
- CASL compliant consent tracking
- One-click unsubscribe
- Multi-channel flexibility
🔥 NEW: Automatic Integration Code Generator
The easiest way to integrate your distribution lists - no manual coding required!
What Is It?
Every distribution list now has a "🔗 Get Integration Code" button that automatically generates ready-to-use integration code for all the methods described in this guide. All URLs, API endpoints, and list IDs are pre-filled for you.
How to Use
- Log into your CRM at https://crm.sagentix.ca
- Navigate to Distribution Lists tab
- Click "🔗 Get Integration Code" on any list
- Choose your integration type from the modal:
- 🌐 Website Form Integration
- ✉️ Email Signature Links
- 📱 Social Media Integration
- 💼 LinkedIn Profile/Company Page
- Click "📋 Copy" to copy the code
- Paste wherever you need it
What You Get
🌐 Website Form Integration - Complete HTML subscription form - Inline CSS styling (no external stylesheets needed) - Full JavaScript implementation for API calls - Success/error message handling - Mobile-responsive design - Ready to paste into any webpage
✉️ Email Signature Links
- Plain URL format: https://...subscribe?listId=xxx&source=email
- HTML format: <a href="...">Subscribe to List Name</a>
- Pre-filled with your list ID
- Tracking parameter included
📱 Social Media Integration - Pre-written engaging post text - Subscription link embedded - Relevant hashtags included - Ready for LinkedIn, Twitter, Facebook, Instagram
💼 LinkedIn Profile/Company Page - Professional formatted text - Perfect for LinkedIn "Contact Info" section - Direct subscription link - Company page friendly
Benefits
✅ Zero Configuration - Everything is pre-filled ✅ No Technical Skills Required - Just copy and paste ✅ List-Specific - Unique code for each distribution list ✅ Production-Ready - Professional, tested code ✅ Time-Saving - Seconds instead of hours
Example Workflow
Old Way (Manual): 1. Read this documentation 2. Copy API endpoint from docs 3. Find your list ID 4. Write HTML form code 5. Write JavaScript for API calls 6. Test and debug 7. Style the form ⏱️ Time: 30-60 minutes
New Way (Automated): 1. Click "🔗 Get Integration Code" 2. Click "📋 Copy" 3. Paste into your website/email/social media ⏱️ Time: 30 seconds
Public Subscription API
Endpoint Details
URL: https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe
Method: POST
Authentication: None required (public endpoint)
Content-Type: application/json
Request Format
{
"email": "user@example.com",
"listId": "your-distribution-list-id",
"firstName": "John",
"lastName": "Doe"
}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Valid email address | |
| listId | string | Yes | Distribution list UUID |
| firstName | string | No | Contact's first name |
| lastName | string | No | Contact's last name |
Response Format
Success (201 Created):
{
"message": "Successfully subscribed to the list",
"contactId": "abc123-contact-id",
"listId": "4f41dfcd-7848-407a-a67d-ef1041f8a1f6"
}
Error (400 Bad Request):
{
"error": "Missing required field: email"
}
Error (500 Internal Server Error):
{
"error": "Failed to process subscription"
}
Example API Call
Using JavaScript Fetch:
async function subscribeToList(email, firstName, lastName) {
try {
const response = await fetch('https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: email,
firstName: firstName,
lastName: lastName,
listId: '4f41dfcd-7848-407a-a67d-ef1041f8a1f6'
})
});
if (!response.ok) {
throw new Error('Subscription failed');
}
const data = await response.json();
console.log('Subscribed successfully:', data);
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
Using cURL:
curl -X POST https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"listId": "4f41dfcd-7848-407a-a67d-ef1041f8a1f6"
}'
Using Python:
import requests
def subscribe_to_list(email, first_name, last_name, list_id):
url = "https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe"
payload = {
"email": email,
"firstName": first_name,
"lastName": last_name,
"listId": list_id
}
response = requests.post(url, json=payload)
if response.status_code == 201:
print("Subscription successful:", response.json())
return response.json()
else:
print("Subscription failed:", response.json())
return None
Website Form Integration
Basic HTML Form
Simple footer signup form:
<!DOCTYPE html>
<html>
<head>
<title>Newsletter Signup</title>
<style>
.subscription-form {
max-width: 500px;
margin: 40px auto;
padding: 30px;
background: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.subscription-form h2 {
margin-top: 0;
color: #333;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
color: #555;
font-weight: 500;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
box-sizing: border-box;
}
.form-group input:focus {
outline: none;
border-color: #4CAF50;
}
.submit-btn {
background: #4CAF50;
color: white;
padding: 12px 30px;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
width: 100%;
}
.submit-btn:hover {
background: #45a049;
}
.submit-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.message {
margin-top: 15px;
padding: 10px;
border-radius: 4px;
text-align: center;
}
.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.consent-text {
font-size: 12px;
color: #666;
margin-top: 10px;
line-height: 1.4;
}
</style>
</head>
<body>
<div class="subscription-form">
<h2>Subscribe to Our Newsletter</h2>
<p>Get the latest updates delivered to your inbox.</p>
<form id="subscribeForm">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" id="firstName" name="firstName" placeholder="John">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" id="lastName" name="lastName" placeholder="Doe">
</div>
<div class="form-group">
<label for="email">Email Address *</label>
<input type="email" id="email" name="email" required placeholder="john@example.com">
</div>
<button type="submit" class="submit-btn" id="submitBtn">Subscribe</button>
<p class="consent-text">
By subscribing, you consent to receive marketing emails from us.
You can unsubscribe at any time using the link in our emails.
</p>
</form>
<div id="message"></div>
</div>
<script>
// Configuration
const API_URL = 'https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe';
const LIST_ID = '4f41dfcd-7848-407a-a67d-ef1041f8a1f6';
document.getElementById('subscribeForm').addEventListener('submit', async (e) => {
e.preventDefault();
const submitBtn = document.getElementById('submitBtn');
const messageDiv = document.getElementById('message');
// Disable submit button
submitBtn.disabled = true;
submitBtn.textContent = 'Subscribing...';
messageDiv.innerHTML = '';
// Get form data
const formData = {
email: document.getElementById('email').value.trim(),
firstName: document.getElementById('firstName').value.trim(),
lastName: document.getElementById('lastName').value.trim(),
listId: LIST_ID
};
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
if (response.ok) {
messageDiv.innerHTML = '<div class="message success">Thank you for subscribing! Check your inbox for a confirmation email.</div>';
document.getElementById('subscribeForm').reset();
} else {
const error = await response.json();
messageDiv.innerHTML = `<div class="message error">Subscription failed: ${error.error || 'Please try again.'}</div>`;
}
} catch (error) {
console.error('Subscription error:', error);
messageDiv.innerHTML = '<div class="message error">Network error. Please check your connection and try again.</div>';
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Subscribe';
}
});
</script>
</body>
</html>
Minimal Footer Form
Compact version for website footers:
<div class="footer-subscribe">
<h3>Stay Updated</h3>
<form id="footerSubscribe" style="display: flex; gap: 10px; max-width: 400px;">
<input
type="email"
id="footerEmail"
placeholder="Your email"
required
style="flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px;"
>
<button
type="submit"
style="padding: 10px 20px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer;"
>
Subscribe
</button>
</form>
<div id="footerMessage" style="margin-top: 10px; font-size: 14px;"></div>
</div>
<script>
document.getElementById('footerSubscribe').addEventListener('submit', async (e) => {
e.preventDefault();
const email = document.getElementById('footerEmail').value;
const messageDiv = document.getElementById('footerMessage');
try {
const response = await fetch('https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: email,
listId: '4f41dfcd-7848-407a-a67d-ef1041f8a1f6'
})
});
if (response.ok) {
messageDiv.innerHTML = '<span style="color: green;">✓ Subscribed successfully!</span>';
document.getElementById('footerEmail').value = '';
} else {
messageDiv.innerHTML = '<span style="color: red;">✗ Subscription failed</span>';
}
} catch (error) {
messageDiv.innerHTML = '<span style="color: red;">✗ Network error</span>';
}
});
</script>
WordPress Integration
Add to your theme's functions.php:
<?php
// Add subscription form shortcode
function crm_subscription_form() {
ob_start();
?>
<div class="crm-subscribe-form">
<form id="crmSubscribeForm" method="post">
<input type="email" name="email" id="crmEmail" placeholder="Enter your email" required>
<input type="text" name="firstName" id="crmFirstName" placeholder="First Name">
<input type="text" name="lastName" id="crmLastName" placeholder="Last Name">
<button type="submit">Subscribe</button>
</form>
<div id="crmMessage"></div>
</div>
<script>
jQuery(document).ready(function($) {
$('#crmSubscribeForm').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: 'https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/subscribe',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
email: $('#crmEmail').val(),
firstName: $('#crmFirstName').val(),
lastName: $('#crmLastName').val(),
listId: '4f41dfcd-7848-407a-a67d-ef1041f8a1f6'
}),
success: function(response) {
$('#crmMessage').html('<p style="color: green;">Subscribed successfully!</p>');
$('#crmSubscribeForm')[0].reset();
},
error: function() {
$('#crmMessage').html('<p style="color: red;">Subscription failed. Please try again.</p>');
}
});
});
});
</script>
<?php
return ob_get_clean();
}
add_shortcode('crm_subscribe', 'crm_subscription_form');
?>
Usage in WordPress:
[crm_subscribe]
Email Signature Links
Basic Subscribe Link
Direct subscription link format:
https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
HTML Email Signature
Professional email signature with subscribe link:
<table style="font-family: Arial, sans-serif; font-size: 14px; color: #333;">
<tr>
<td style="padding-right: 20px; border-right: 2px solid #4CAF50;">
<strong style="font-size: 16px;">John Doe</strong><br>
Marketing Director<br>
Company Name Inc.<br>
<a href="mailto:john@company.com">john@company.com</a><br>
<a href="tel:+15551234567">+1 (555) 123-4567</a>
</td>
<td style="padding-left: 20px;">
<a href="https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6"
style="background: #4CAF50; color: white; padding: 8px 16px; text-decoration: none; border-radius: 4px; display: inline-block;">
📧 Subscribe to Our Newsletter
</a>
<br><br>
<a href="https://company.com" style="color: #4CAF50; text-decoration: none;">
🌐 Visit Our Website
</a>
</td>
</tr>
</table>
Plain Text Email Signature
For plain text emails:
--
John Doe
Marketing Director
Company Name Inc.
john@company.com | +1 (555) 123-4567
📧 Subscribe to our newsletter:
https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
🌐 Visit us: https://company.com
Gmail Signature Setup
- Open Gmail Settings (gear icon > See all settings)
- Scroll to "Signature" section
- Click "Create new" signature
- Paste the HTML signature code
- Replace
4f41dfcd-7848-407a-a67d-ef1041f8a1f6with your actual list ID - Click "Save Changes"
Outlook Signature Setup
- Open Outlook > File > Options > Mail
- Click "Signatures..."
- Click "New" to create a signature
- Switch to HTML editor (Format menu)
- Paste the HTML signature code
- Replace
4f41dfcd-7848-407a-a67d-ef1041f8a1f6with your actual list ID - Click "OK" to save
Social Media Integration
LinkedIn Profile Link
Add to LinkedIn "Featured" section or About:
📧 Subscribe to my newsletter: https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
Get weekly insights on [your topic] delivered to your inbox.
Twitter/X Bio Link
Add to your bio (character limit friendly):
📧 Newsletter: crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
Tweet for subscribers:
Want to stay updated? Subscribe to our newsletter! 📧
👉 https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
✅ Weekly insights
✅ Industry trends
✅ Exclusive content
#Newsletter #Subscribe
Facebook Page
Add to "About" section:
Subscribe to Our Newsletter
Get the latest updates delivered to your inbox.
https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
Facebook Post:
🚀 Join our newsletter community!
Get exclusive content, tips, and insights delivered weekly.
Subscribe here: https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
✓ No spam, ever
✓ Unsubscribe anytime
✓ CASL compliant
Instagram Bio Link
Use link shortener for cleaner appearance:
📧 Newsletter → bit.ly/your-short-link
Instagram Story with Link Sticker:
1. Create story with subscribe call-to-action
2. Add link sticker
3. Paste: https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
4. Customize sticker text: "Subscribe"
YouTube Channel
Add to channel description:
📬 SUBSCRIBE TO OUR EMAIL NEWSLETTER
Stay updated with exclusive content not available on YouTube!
👉 https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
Add as end screen element:
1. Upload custom end screen with subscribe CTA
2. Link to external website
3. URL: https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
QR Code Registration
Generating QR Codes
Option 1: Online QR Code Generator
- Visit: https://www.qr-code-generator.com/
- Select "URL" type
- Enter:
https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6 - Customize design (optional)
- Download high-resolution PNG
Option 2: Using Python
import qrcode
# Generate QR code
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=4,
)
qr.add_data('https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6')
qr.make(fit=True)
# Create image
img = qr.make_image(fill_color="black", back_color="white")
img.save("newsletter_qr.png")
Option 3: Using Node.js
const QRCode = require('qrcode');
const url = 'https://crm.sagentix.ca/subscribe?list=4f41dfcd-7848-407a-a67d-ef1041f8a1f6';
QRCode.toFile('newsletter_qr.png', url, {
color: {
dark: '#000000',
light: '#FFFFFF'
},
width: 300
}, function (err) {
if (err) throw err;
console.log('QR code saved!');
});
QR Code Use Cases
1. Business Cards - Add QR code to back of card - Caption: "Scan to subscribe to our newsletter" - Size: 1" x 1" (2.5cm x 2.5cm)
2. Print Flyers - Bottom corner or center - Clear call-to-action - Size: 2" x 2" (5cm x 5cm)
3. Conference Booth - Large poster with QR code - Sign: "Scan to stay in touch!" - Size: 6" x 6" (15cm x 15cm)
4. Product Packaging - Inside lid or on label - "Join our community" - Size: 0.75" x 0.75" (2cm x 2cm)
5. Restaurant Table Tents - Special offers newsletter - "Get exclusive deals" - Size: 3" x 3" (7.5cm x 7.5cm)
6. Event Badge - Conference attendee badges - "Connect with me" - Size: 1" x 1" (2.5cm x 2.5cm)
QR Code Best Practices
✅ Do: - Test QR code before printing - Use high error correction (H level) - Ensure high contrast (dark on light) - Include caption explaining what it does - Make it large enough (minimum 1" / 2.5cm) - Use URL shortener for tracking
❌ Don't: - Use low resolution images - Place on textured/patterned backgrounds - Make it too small to scan - Forget to test from typical scanning distance
LinkedIn Integration (Planned)
Planned Features
The LinkedIn integration feature is planned for future implementation. It will allow:
- Connection Import
- OAuth authentication with LinkedIn
- Import 1st-degree connections
- Automatic contact creation
-
Bulk list assignment
-
Profile Sync
- Sync profile information
- Company details
- Job titles
-
Profile photos
-
InMail Integration
- Send campaigns via InMail
- Track message engagement
- CASL compliance maintained
Current Workaround
Manual LinkedIn Connection Export:
- Go to LinkedIn > Settings & Privacy > Data Privacy
- Click "Get a copy of your data"
- Select "Connections"
- Download CSV file
- Import via CRM's Excel import feature
- Manually add to distribution list
Implementation Timeline
- Status: Planned
- Effort: Medium (2-4 hours)
- Priority: Low (workaround available)
- Blockers: LinkedIn API access approval required
Technical Requirements
When implemented, will require: - LinkedIn API application - OAuth 2.0 implementation - Member permissions - Rate limiting (100 requests per day for free tier)
Unsubscribe Mechanism
Unsubscribe Link Format
Every email campaign automatically includes an unsubscribe link:
https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/unsubscribe?email=user@example.com&listId=4f41dfcd-7848-407a-a67d-ef1041f8a1f6
How It Works
- User clicks unsubscribe link in email
- GET request to
/public/unsubscribeendpoint - Contact status updated to "unsubscribed"
- Removed from distribution list
- Confirmation page displayed
- User receives confirmation email
Manual Unsubscribe Implementation
Frontend unsubscribe page:
<!DOCTYPE html>
<html>
<head>
<title>Unsubscribe</title>
<style>
.container {
max-width: 500px;
margin: 100px auto;
padding: 40px;
text-align: center;
background: #f9f9f9;
border-radius: 8px;
}
.success {
color: #4CAF50;
font-size: 48px;
margin-bottom: 20px;
}
h1 {
color: #333;
margin-bottom: 10px;
}
p {
color: #666;
line-height: 1.6;
}
.btn {
display: inline-block;
margin-top: 20px;
padding: 12px 30px;
background: #4CAF50;
color: white;
text-decoration: none;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="container">
<div class="success">✓</div>
<h1>You've Been Unsubscribed</h1>
<p>We're sorry to see you go! You have been successfully removed from our mailing list.</p>
<p>You will no longer receive emails from us.</p>
<a href="https://yourwebsite.com" class="btn">Back to Website</a>
</div>
<script>
// Parse URL parameters
const params = new URLSearchParams(window.location.search);
const email = params.get('email');
const listId = params.get('listId');
// Call unsubscribe API
if (email && listId) {
fetch(`https://zqkprqp60h.execute-api.ca-central-1.amazonaws.com/Prod/public/unsubscribe?email=${email}&listId=${listId}`)
.then(response => response.json())
.then(data => console.log('Unsubscribed:', data))
.catch(error => console.error('Error:', error));
}
</script>
</body>
</html>
CASL Compliance
All unsubscribe mechanisms are CASL compliant:
✅ One-click unsubscribe (no login required) ✅ Processed immediately ✅ Confirmation provided ✅ Persistent (cannot be re-subscribed without consent) ✅ Available in every email ✅ Clear and conspicuous
CASL Compliance
Canadian Anti-Spam Legislation Requirements
All subscription methods comply with CASL:
- Express Consent
- All subscriptions are opt-in
- Clear purpose stated
- Consent date tracked
-
Audit trail maintained
-
Identification Requirements
- Sender name in every email
- Valid physical mailing address
-
Contact information provided
-
Unsubscribe Mechanism
- Available in every message
- Free of charge
- No login required
- One-click process
-
Processed within 10 business days (we process immediately)
-
Record Keeping
- Consent date stored
- Subscription method tracked
- Unsubscribe date recorded
- Full audit trail
Consent Tracking
Every subscription records: - Email address - Subscription date (ISO 8601 format) - Subscription method (website, email, QR code, etc.) - IP address (optional, for fraud prevention) - List ID - Contact creation timestamp
Legal Requirements Met
✅ Express consent obtained ✅ Clear identification of sender ✅ Subject matter stated ✅ Physical mailing address included ✅ Unsubscribe mechanism provided ✅ Consent records maintained ✅ Unsubscribe honored immediately
Troubleshooting
Common Issues
Issue 1: Subscription Not Working
Symptoms: - Form submission returns error - No contact created in CRM
Solutions: 1. Verify API URL is correct 2. Check list ID is valid 3. Ensure CORS is enabled on API Gateway 4. Verify Lambda function is deployed 5. Check CloudWatch logs for errors
Issue 2: CORS Errors
Symptoms: - Browser console shows CORS error - Request blocked by browser
Solutions: 1. Add CORS headers to Lambda response:
return {
'statusCode': 201,
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
},
'body': json.dumps(response_body)
}
- Enable CORS in API Gateway:
- Go to API Gateway console
- Select your API
- Choose the resource
- Enable CORS
- Deploy API
Issue 3: Duplicate Contacts
Symptoms: - Same email subscribed multiple times - Multiple contact records with same email
Solutions: - The system automatically prevents duplicates by email - If issue persists, check Lambda function logic - Use duplicate detection tool in CRM
Issue 4: Unsubscribe Not Working
Symptoms: - User still receives emails after unsubscribing - Unsubscribe link returns error
Solutions: 1. Verify unsubscribe endpoint is deployed 2. Check CloudWatch logs for errors 3. Confirm contact status updated to "unsubscribed" 4. Verify campaign send logic excludes unsubscribed contacts
Issue 5: QR Code Not Scanning
Symptoms: - QR code won't scan - Scanner app doesn't recognize it
Solutions: 1. Regenerate QR code at higher resolution 2. Ensure sufficient size (minimum 1" / 2.5cm) 3. Use high error correction level 4. Test on white paper with dark ink 5. Verify URL is correct before generating
Testing Checklist
Before deploying subscription methods:
✅ Test subscription form with valid data ✅ Test with missing required fields ✅ Test with invalid email format ✅ Test with duplicate email ✅ Verify contact created in CRM ✅ Verify list membership created ✅ Test unsubscribe link ✅ Check all CloudWatch logs ✅ Test from mobile device ✅ Test QR code scanning
Support Resources
- CloudWatch Logs:
/aws/lambda/crm-subscribe-public-dev - API Gateway Logs: Enable in settings
- DynamoDB: Check
CrmContacts-devtable - Documentation: See COMPLETE_FEATURE_GUIDE.md
Summary
This CRM platform provides comprehensive subscription methods suitable for any marketing channel:
- Website Forms: Full featured forms with validation
- Email Signatures: Professional signature links
- Social Media: Platform-specific integration
- QR Codes: Print-friendly registration
- Public API: Custom integration support
All methods are: - ✅ CASL compliant - ✅ No login required - ✅ Duplicate-safe - ✅ Instantly processed - ✅ One-click unsubscribe
Next Steps: 1. Get your distribution list ID from the CRM 2. Choose your preferred subscription method 3. Customize the examples with your API URL and list ID 4. Test thoroughly before deployment 5. Monitor CloudWatch logs for issues
For complete feature documentation, see COMPLETE_FEATURE_GUIDE.md
Document Version: 1.0 Last Updated: October 27, 2025 Maintained By: CRM Platform Team