SaaS-Produkte sind strukturell event-getrieben — User-Aktion löst Geschäfts-Logik aus, Logik triggert Nebenwirkungen. E-Mail ist eine der wichtigsten Nebenwirkungen. Email API ist für event-getriebene SaaS-Architekturen die strukturell überlegene Wahl gegenüber SMTP-Relay.
Was event-getriebene Workflows ausmacht
User klickt "Sign up"
↓
Anwendung erstellt Account
↓
Anwendung publiziert Event: "user.signed_up"
↓
HTTP-Response geht zurück (User sieht Dashboard)
↓
Parallel: mehrere Subscriber konsumieren Event
├─ CRM-Sync-Service
├─ Analytics-Service
├─ Onboarding-Service
└─ E-Mail-Service (Welcome-Mail senden)
Warum Email API strukturell besser passt
Webhooks für Engagement-Events: wenn der User die Welcome-Mail öffnet, wird "email.opened" publiziert. Andere Services können reagieren.
Idempotency-Keys: wenn das gleiche Trigger-Event zweimal verarbeitet wird, würde SMTP zwei Mails versenden. Mit Idempotency-Keys erkennt die API Duplicates.
Async-by-Default: API-Aufrufe sind stateless. SMTP-Konnektion-Pools brauchen Verwaltung.
Microservice-Native: HTTP ist die natürliche Sprache der Microservices.
Architektur-Pattern
Pattern A: Direkte Integration
def handle_user_signed_up(event):
user = User.get(event['user_id'])
response = email_api.send(
to=user.email,
template='welcome',
template_data={'first_name': user.first_name},
idempotency_key=f'welcome-{user.id}-v1'
)
Einfach. Aber: tight coupling, jeder Subscriber verwaltet API-Credentials.
Pattern B: Dedizierter Mail-Service
# Subscriber publiziert nur Event
def handle_user_signed_up(event):
user = User.get(event['user_id'])
event_bus.publish('mail.send_requested', {
'template': 'welcome',
'recipient_id': user.id,
'template_data': {'first_name': user.first_name},
'idempotency_key': f'welcome-{user.id}-v1'
})
# Mail-Service handled API-Integration
class MailService:
def handle_send_requested(event):
recipient = User.get(event['recipient_id'])
response = email_api.send(
to=recipient.email,
template=event['template'],
template_data=event['template_data'],
idempotency_key=event['idempotency_key']
)
Standard für mittelständische SaaS-Architekturen.
Webhook-Verarbeitung für Choreography
@app.route('/webhooks/email-events', methods=['POST'])
def handle_email_webhook():
if not verify_signature(request.headers, request.body):
abort(401)
events = json.loads(request.body)
for event in events:
event_bus.publish(f'email.{event["event"]}', {
'recipient_email': event['recipient_email'],
'message_id': event['message_id'],
'custom_args': event.get('custom_args', {}),
'timestamp': event['timestamp']
})
return '', 200
class CRMService:
def handle_email_opened(event):
lead_id = event['custom_args'].get('lead_id')
if lead_id:
Lead.get(lead_id).increment_engagement_score(2)
Idempotency-Strategien
# Welcome-Mail nach signup
idempotency_key = f"welcome-{user.id}-v1"
# Order-Confirmation
idempotency_key = f"order-confirmation-{order.id}-v2"
# Re-Engagement (wiederholt zulässig)
idempotency_key = f"re-engagement-{user.id}-{campaign_id}-{step}"
Bei Schema-Änderung Version erhöhen — sonst wird die neue Mail nicht versendet.
Custom Args für Event-Korrelation
email_api.send(
to=user.email,
template='welcome',
custom_args={
'user_id': user.id,
'email_type': 'welcome',
'campaign_id': 'trial-onboarding-v3',
'sequence_step': 1,
'tenant_id': user.tenant_id
}
)
DACH-spezifische Aspekte
Multi-Tenant-Strukturen mit verschiedenen Sprachen (DE, AT, CH unterscheiden sich subtil). Templates pro Locale, Personalisierung mit korrekter Anrede ("Sehr geehrte Frau Müller" vs. "Liebe Anna"), AT-Begriffe (Rechnung statt Faktura).
DSGVO-konforme Webhook-Verarbeitung: Custom Args sollten keine Klartext-personenbezogenen Daten enthalten, sondern nur User-IDs.
Bei Mehr-Mandanten-SaaS mit Custom-Domain pro Tenant: jeder Tenant kann eigene From-Domain haben. Email API muss das unterstützen — bei Authorize Hosting im Pro-Tarif Standard.
API-Setup für Ihre SaaS-Architektur?
Wir besprechen Ihre Microservice-Architektur und konfigurieren API-Setup mit passenden Webhook-Endpunkten und Multi-Tenant-Support.