Documentation Index
Fetch the complete documentation index at: https://docs.truthlocks.com/llms.txt
Use this file to discover all available pages before exploring further.
Production-grade email delivery using AWS Simple Email Service (SES) with bounce handling, suppression management, and observability.
Architecture
Truthlocks uses AWS SES for all transactional emails. The integration includes:
- SES Provider: Direct integration with SES v2 API for sending emails
- SNS Webhooks: Real-time bounce/complaint notifications via SNS topics
- Suppression List: Automatic suppression of hard bounces and complaints
- Environment Gating: Log-only mode for development, SES for production
AWS SES setup
1. Verify domain
Verify your sending domain in SES console:
# Using AWS CLI
aws ses verify-domain-identity --domain truthlocks.com --region us-east-1
# Get DKIM tokens (add to DNS)
aws ses verify-domain-dkim --domain truthlocks.com --region us-east-1
Add the following records to your domain DNS:
| Type | Name | Value |
|---|
| TXT | _amazonses.truthlocks.com | (verification token from SES) |
| CNAME | (DKIM selector 1) | (DKIM value from SES) |
| MX | mail.truthlocks.com | feedback-smtp.us-east-1.amazonses.com |
| TXT | mail.truthlocks.com | v=spf1 include:amazonses.com ~all |
3. Request production access
New SES accounts are in sandbox mode. Request production access in the SES console to send emails to unverified addresses.
Environment variables
| Variable | Required | Description |
|---|
EMAIL_MODE | Yes | log (dev) or ses (prod) |
SES_REGION | If ses | AWS region (e.g., us-east-1) |
SES_FROM | If ses | Sender address (e.g., no-reply@truthlocks.com) |
SES_REPLY_TO | No | Reply-to address for all outgoing emails |
SES_CONFIGURATION_SET | No | SES configuration set for tracking and reputation management |
SES_WEBHOOK_SECRET | No | Secret for validating SNS webhook signatures |
EMAIL_CHECK_SUPPRESSION | No | When true, checks the suppression list before every send attempt |
In ENV=production, the service will fail to start if SES_REGION and
SES_FROM are not configured.
Bounce & complaint handling
SES notifications are received via an SNS webhook at /v1/notifications/ses-events.
Event types
- Bounce (Permanent): Hard bounce — email suppressed automatically
- Bounce (Transient): Soft bounce — logged but not suppressed
- Complaint: User marked as spam — email suppressed automatically
- Delivery: Successful delivery — logged for observability
Suppression list management
Suppressed emails are stored in the email_suppressions table and will not receive future emails. The API returns EMAIL_SUPPRESSED error code.
-- Check if email is suppressed
SELECT * FROM email_suppressions WHERE email = 'user@example.com';
-- View recent suppressions
SELECT email, reason, suppressed_at
FROM email_suppressions
ORDER BY suppressed_at DESC
LIMIT 20;
Email sender management
You can manage sender identities and custom SMTP configuration from Settings > Email in the tenant console. This is useful when your organization requires emails to originate from your own domain or mail infrastructure.
Adding a sender
Open email settings
Navigate to Settings > Email in the tenant console.
Add a new sender
Click Add Sender and provide:
- From email (required) — the address emails are sent from (e.g.,
noreply@agency.gov)
- From name — display name shown to recipients
- Reply-to — where replies are directed
Verify the sender
New senders start in PENDING status. Click Verify to trigger SES identity verification. Once SES confirms the domain, the sender moves to VERIFIED status.
Configuring custom SMTP
Enterprise and government tenants can bypass SES entirely by attaching a custom SMTP server to a verified sender. Once configured, all emails for that tenant route through your SMTP server.
Select a verified sender
In Settings > Email, choose a sender with VERIFIED or ACTIVE status.
Configure SMTP
Click Configure SMTP and provide:
- SMTP host — your mail server hostname
- SMTP port — typically
587 (STARTTLS) or 465 (TLS)
- Username and Password — SMTP authentication credentials
- Use TLS — enable for encrypted connections (recommended)
Send a test email
After saving, send a test email to confirm delivery. The sender status changes to ACTIVE once the first email is sent successfully.
Custom SMTP is particularly useful for government tenants that require emails
to originate from their own mail infrastructure. See the
B2G Procurement Pack for the full
enterprise onboarding email flow.
Email template reference
Truthlocks uses named templates for all transactional emails. Each template supports placeholder substitution and is routed through either AWS SES or a tenant-configured custom SMTP server.
Onboarding & invitations
| Template name | Trigger | Description | Placeholders |
|---|
enterprise-onboarding-invite | Government tenant creation or lead qualification | Branded invite for enterprise/government administrators | {{organization_name}}, {{invite_url}} |
issuer-onboarding-invite | Standard tenant creation | Welcome email for non-government issuers | {{organization_name}}, {{invite_url}} |
team-invite | Team member invitation | Invite for new team members within a tenant | {{team_name}}, {{invite_url}} |
verification-onboarding | Verifier registration | Onboarding guide for verification partners | {{organization_name}}, {{invite_url}} |
Account & security
| Template name | Trigger | Description | Placeholders |
|---|
email-verification | Account signup | Confirms the user’s email address | {{VERIFY_URL}} |
password-reset | Password reset request | Secure password reset link | {{reset_url}} |
api-key-issued | API key creation | Confirms a new API key was created for the account | {{key_prefix}}, {{created_at}} |
security-review-response | Security review completed | Notifies the tenant of a security review outcome | {{review_status}}, {{review_summary}} |
incident-notification | Security incident | Alerts administrators to a platform security event | {{incident_title}}, {{severity}} |
Issuer lifecycle
| Template name | Trigger | Description | Placeholders |
|---|
issuer-approved | Issuer application approved | Confirms approval and shows the assigned trust tier | {{assigned_tier}}, {{console_url}} |
issuer-rejected | Issuer application rejected | Notifies the applicant with the rejection reason | {{rejection_reason}} |
issuer-evidence-request | Additional evidence needed | Requests compliance evidence for a trust tier application | {{trust_tier_name}}, {{requested_evidence_description}}, {{upload_url}} |
Enterprise onboarding sequence
Government and institutional tenants receive a sequence of lifecycle emails as they progress through onboarding. These are sent automatically at each stage.
| Template name | Stage | Description |
|---|
invite_kickoff | Invitation | Welcome to Truthlocks Enterprise — links to the onboarding wizard |
sandbox_ready | Sandbox provisioned | Confirms the sandbox environment is ready for integration testing |
evidence_request | Compliance review | Requests compliance documentation needed for production access |
billing_activation | Billing setup | Confirms billing is active and the subscription plan is in place |
webhooks_test | Integration testing | Confirms webhook endpoints are configured and receiving test events |
incident_notification | Ongoing | Alerts the tenant administrator to any platform incidents |
approval_go_live | Production approved | Confirms production access is granted and the tenant is live |
The onboarding sequence is fully automated. As a platform admin, you trigger
it by creating a tenant with the GOVERNMENT type or by qualifying a lead in
the leads pipeline.
Other notifications
| Template name | Trigger | Description |
|---|
billing-upgrade-required | Usage exceeds plan limits | Prompts the tenant to upgrade their billing plan |
webhook-test-success | Webhook test event delivered | Confirms a test webhook was delivered successfully |
Government tenants (GOVERNMENT type) automatically receive the
enterprise-onboarding-invite template instead of the standard issuer
welcome. See the B2G Procurement Pack
for details on the enterprise onboarding flow.
Troubleshooting
Email not received
- Check logs for
email_sent or email_send_failed events
- Verify the recipient email is not in
email_suppressions
- Check SES console for sending quota and reputation
- Verify DKIM/SPF records are correctly configured
Common error codes
| Error code | Meaning | Resolution |
|---|
EMAIL_SUPPRESSED | Recipient is on the suppression list | Remove from email_suppressions if the issue is resolved |
SES_ERROR | AWS SES rejected the send request | Check SES console for quota or configuration issues |
CONFIG_ERROR | Missing or invalid email configuration | Verify environment variables are set correctly |
INVALID_EMAIL | Recipient email address failed format validation | Confirm the email address is valid |
Observability
All email operations are logged with structured fields:
{
"level": "info",
"msg": "email_sent",
"message_id": "0102...",
"to": "admin@agency.gov",
"subject": "You've been invited to Truthlocks Enterprise",
"template_name": "enterprise-onboarding-invite",
"tenant_id": "tnt_abc123",
"duration_ms": 245
}
Key log events to monitor:
| Event | Level | Description |
|---|
email_sent | info | Email delivered to SES or SMTP successfully |
email_send_failed | error | Email send attempt failed |
email_suppressed | warn | Send skipped because the recipient is suppressed |
ses_webhook_received | info | SNS notification received from SES |
ses_webhook_error | error | Failed to process an SNS notification |