vybekiit 0.7.4 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +10483 -1704
- package/dist/global-skills/aws-cdk/SKILL.md +2 -1
- package/dist/global-skills/aws-cloudformation/SKILL.md +2 -1
- package/dist/global-skills/aws-serverless/SKILL.md +45 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
- package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
- package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
- package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
- package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
- package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
- package/dist/global-skills/aws-serverless/references/production.md +78 -415
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +92 -619
- package/dist/global-skills/claimable-postgres/SKILL.md +60 -49
- package/dist/global-skills/design-my-data/SKILL.md +2 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +8 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +2 -0
- package/dist/global-skills/eas-hosting/SKILL.md +8 -0
- package/dist/global-skills/eas-observe/SKILL.md +30 -8
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/references/metrics.md +54 -3
- package/dist/global-skills/eas-observe/references/queries.md +78 -17
- package/dist/global-skills/eas-observe/references/setup.md +164 -5
- package/dist/global-skills/eas-observe/references/third-party.md +136 -0
- package/dist/global-skills/eas-simulator/SKILL.md +63 -11
- package/dist/global-skills/eas-simulator/references/controllers.md +21 -2
- package/dist/global-skills/eas-simulator/references/run-your-app.md +16 -11
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -5
- package/dist/global-skills/eas-update-insights/SKILL.md +8 -0
- package/dist/global-skills/eas-workflows/SKILL.md +15 -10
- package/dist/global-skills/eas-workflows/scripts/package.json +2 -7
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
- package/dist/global-skills/email-best-practices/README.md +63 -0
- package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
- package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
- package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
- package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
- package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
- package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
- package/dist/global-skills/email-best-practices/tests/README.md +35 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
- package/dist/global-skills/expo-animation/LICENSE +21 -0
- package/dist/global-skills/expo-animation/RECIPES.md +385 -0
- package/dist/global-skills/expo-animation/SKILL.md +267 -0
- package/dist/global-skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +53 -4
- package/dist/global-skills/expo-data-fetching/SKILL.md +8 -0
- package/dist/global-skills/expo-design-system/SKILL.md +356 -0
- package/dist/global-skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-design-system/references/audit.md +185 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +8 -0
- package/dist/global-skills/expo-dom/SKILL.md +8 -0
- package/dist/global-skills/expo-examples/SKILL.md +8 -0
- package/dist/global-skills/expo-migrate-module/SKILL.md +113 -0
- package/dist/global-skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +73 -0
- package/dist/global-skills/expo-migrate-module/references/example.md +212 -0
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +306 -0
- package/dist/global-skills/expo-module/SKILL.md +11 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-project-structure/SKILL.md +114 -0
- package/dist/global-skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/SKILL.md +8 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +66 -33
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +8 -0
- package/dist/global-skills/expo-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +15 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +8 -0
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +129 -0
- package/dist/global-skills/extension-to-functions-codebase/references/configuration-migration.md +161 -0
- package/dist/global-skills/extension-to-functions-codebase/references/destructuring-shim.md +122 -0
- package/dist/global-skills/extension-to-functions-codebase/references/signature-mapping.md +84 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +61 -19
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +6 -3
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-auth-basics/SKILL.md +4 -2
- package/dist/global-skills/firebase-basics/SKILL.md +5 -5
- package/dist/global-skills/firebase-crashlytics/SKILL.md +2 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +3 -6
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +4 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +4 -1
- package/dist/global-skills/harden/SKILL.md +2 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-feature-flags/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/api.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/django.md +38 -5
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/flask.md +17 -5
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +7 -5
- package/dist/global-skills/instrument-feature-flags/references/go.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ios.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/java.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +74 -8
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/php.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/python.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/rust.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/usage.md +41 -4
- package/dist/global-skills/instrument-feature-flags/references/web.md +7 -5
- package/dist/global-skills/instrument-product-analytics/SKILL.md +2 -1
- package/dist/global-skills/instrument-product-analytics/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +12 -14
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +25 -21
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +75 -55
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +3 -6
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +26 -16
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +8 -5
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +4 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +3 -3
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +8 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +20 -8
- package/dist/global-skills/instrument-product-analytics/references/android.md +46 -4
- package/dist/global-skills/instrument-product-analytics/references/angular.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/astro.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +7 -4
- package/dist/global-skills/instrument-product-analytics/references/django.md +38 -5
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/flask.md +17 -5
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +49 -4
- package/dist/global-skills/instrument-product-analytics/references/go.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +38 -7
- package/dist/global-skills/instrument-product-analytics/references/ios.md +14 -4
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +74 -8
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +39 -7
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +40 -4
- package/dist/global-skills/instrument-product-analytics/references/php.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +21 -17
- package/dist/global-skills/instrument-product-analytics/references/python.md +15 -5
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +41 -7
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +42 -6
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +31 -7
- package/dist/global-skills/instrument-product-analytics/references/usage.md +41 -4
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +42 -6
- package/dist/global-skills/manifest.json +6 -1
- package/dist/global-skills/neon/SKILL.md +235 -121
- package/dist/global-skills/neon-ai-gateway/SKILL.md +95 -16
- package/dist/global-skills/neon-functions/SKILL.md +242 -152
- package/dist/global-skills/neon-functions/references/ai-sdk.md +9 -3
- package/dist/global-skills/neon-functions/references/mastra-studio.md +1 -1
- package/dist/global-skills/neon-functions/references/mcp.md +13 -4
- package/dist/global-skills/neon-functions/references/sentry.md +165 -52
- package/dist/global-skills/neon-functions/references/sse.md +23 -6
- package/dist/global-skills/neon-object-storage/SKILL.md +40 -16
- package/dist/global-skills/neon-postgres/SKILL.md +63 -262
- package/dist/global-skills/neon-postgres-branches/SKILL.md +61 -50
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +22 -3
- package/dist/global-skills/resend/SKILL.md +6 -6
- package/dist/global-skills/resend/references/automations.md +2 -2
- package/dist/global-skills/resend/references/broadcasts.md +11 -3
- package/dist/global-skills/resend/references/domains.md +25 -3
- package/dist/global-skills/resend/references/installation.md +7 -7
- package/dist/global-skills/setup-payments/SKILL.md +4 -5
- package/dist/global-skills/stripe-best-practices/SKILL.md +32 -7
- package/dist/global-skills/stripe-best-practices/references/billing.md +11 -1
- package/dist/global-skills/stripe-best-practices/references/payments.md +23 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +21 -11
- package/dist/global-skills/stripe-best-practices/references/tax.md +116 -11
- package/dist/global-skills/supabase/CHANGELOG.md +25 -0
- package/dist/global-skills/supabase/SKILL.md +5 -1
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +30 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -1
- package/dist/global-skills/use-kit-mcp/SKILL.md +5 -5
- package/dist/global-skills/use-railway/SKILL.md +4 -4
- package/dist/global-skills/use-railway/references/iac.md +206 -57
- package/dist/global-skills/use-railway/scripts/railway-api.sh +7 -2
- package/dist/global-skills/xcode-project-setup/SKILL.md +2 -0
- package/package.json +12 -9
- package/LICENSE.md +0 -47
- package/dist/global-skills/eas-workflows/scripts/validate.js +0 -84
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +0 -118
- package/dist/global-skills/neon-functions/references/hono-websockets.md +0 -145
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Sending Reliability
|
|
2
|
+
|
|
3
|
+
Ensuring emails are sent exactly once and handling failures gracefully.
|
|
4
|
+
|
|
5
|
+
## Idempotency
|
|
6
|
+
|
|
7
|
+
Prevent duplicate emails when retrying failed requests.
|
|
8
|
+
|
|
9
|
+
### The Problem
|
|
10
|
+
|
|
11
|
+
Network issues, timeouts, or server errors can leave you uncertain if an email was sent. Retrying without idempotency risks sending duplicates.
|
|
12
|
+
|
|
13
|
+
### Solution: Idempotency Keys
|
|
14
|
+
|
|
15
|
+
Send a unique key with each request. If the same key is sent again, the server returns the original response instead of sending another email.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Generate deterministic key based on the business event
|
|
19
|
+
const idempotencyKey = `password-reset-${userId}-${resetRequestId}`;
|
|
20
|
+
|
|
21
|
+
await resend.emails.send({
|
|
22
|
+
from: 'noreply@example.com',
|
|
23
|
+
to: user.email,
|
|
24
|
+
subject: 'Reset your password',
|
|
25
|
+
html: emailHtml,
|
|
26
|
+
}, {
|
|
27
|
+
headers: {
|
|
28
|
+
'Idempotency-Key': idempotencyKey
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Key Generation Strategies
|
|
34
|
+
|
|
35
|
+
| Strategy | Example | Use When |
|
|
36
|
+
|----------|---------|----------|
|
|
37
|
+
| Event-based | `order-confirm-${orderId}` | One email per event (recommended) |
|
|
38
|
+
| Request-scoped | `reset-${userId}-${resetRequestId}` | Retries within same request |
|
|
39
|
+
| UUID | `crypto.randomUUID()` | No natural key (generate once, reuse on retry) |
|
|
40
|
+
|
|
41
|
+
**Best practice:** Use deterministic keys based on the business event. If you retry the same logical send, the same key must be generated. Avoid `Date.now()` or random values generated fresh on each attempt.
|
|
42
|
+
|
|
43
|
+
**Key expiration:** Idempotency keys are typically cached for 24 hours. Retries within this window return the original response. After expiration, the same key triggers a new send—so complete your retry logic well within 24 hours.
|
|
44
|
+
|
|
45
|
+
## Retry Logic
|
|
46
|
+
|
|
47
|
+
Handle transient failures with exponential backoff.
|
|
48
|
+
|
|
49
|
+
### When to Retry
|
|
50
|
+
|
|
51
|
+
| Error Type | Retry? | Notes |
|
|
52
|
+
|------------|--------|-------|
|
|
53
|
+
| 5xx (server error) | ✅ Yes | Transient, likely to resolve |
|
|
54
|
+
| 429 (rate limit) | ✅ Yes | Wait for rate limit window |
|
|
55
|
+
| 4xx (client error) | ❌ No | Fix the request first |
|
|
56
|
+
| Network timeout | ✅ Yes | Transient |
|
|
57
|
+
| DNS failure | ✅ Yes | May be transient |
|
|
58
|
+
|
|
59
|
+
### Exponential Backoff
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
async function sendWithRetry(emailData, maxRetries = 3) {
|
|
63
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
64
|
+
try {
|
|
65
|
+
return await resend.emails.send(emailData);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (!isRetryable(error) || attempt === maxRetries - 1) {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
|
|
71
|
+
await sleep(delay + Math.random() * 1000); // Add jitter
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isRetryable(error) {
|
|
77
|
+
return error.statusCode >= 500 ||
|
|
78
|
+
error.statusCode === 429 ||
|
|
79
|
+
error.code === 'ETIMEDOUT';
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Backoff schedule:** 1s → 2s → 4s → 8s (with jitter to prevent thundering herd)
|
|
84
|
+
|
|
85
|
+
## Error Handling
|
|
86
|
+
|
|
87
|
+
### Common Error Codes
|
|
88
|
+
|
|
89
|
+
| Code | Meaning | Action |
|
|
90
|
+
|------|---------|--------|
|
|
91
|
+
| 400 | Bad request | Fix payload (invalid email, missing field) |
|
|
92
|
+
| 401 | Unauthorized | Check API key |
|
|
93
|
+
| 403 | Forbidden | Check permissions, domain verification |
|
|
94
|
+
| 404 | Not found | Check endpoint URL |
|
|
95
|
+
| 422 | Validation error | Fix request data |
|
|
96
|
+
| 429 | Rate limited | Back off, retry after delay |
|
|
97
|
+
| 500 | Server error | Retry with backoff |
|
|
98
|
+
| 503 | Service unavailable | Retry with backoff |
|
|
99
|
+
|
|
100
|
+
### Error Handling Pattern
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
try {
|
|
104
|
+
const result = await resend.emails.send(emailData);
|
|
105
|
+
await logSuccess(result.id, emailData);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (error.statusCode === 429) {
|
|
108
|
+
await queueForRetry(emailData, error.retryAfter);
|
|
109
|
+
} else if (error.statusCode >= 500) {
|
|
110
|
+
await queueForRetry(emailData);
|
|
111
|
+
} else {
|
|
112
|
+
await logFailure(error, emailData);
|
|
113
|
+
await alertOnCriticalEmail(emailData); // For password resets, etc.
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Queuing for Reliability
|
|
119
|
+
|
|
120
|
+
For critical emails, use a queue to ensure delivery even if the initial send fails.
|
|
121
|
+
|
|
122
|
+
**Benefits:**
|
|
123
|
+
- Survives application restarts
|
|
124
|
+
- Automatic retry handling
|
|
125
|
+
- Rate limit management
|
|
126
|
+
- Audit trail
|
|
127
|
+
|
|
128
|
+
**Simple pattern:**
|
|
129
|
+
1. Write email to queue/database with "pending" status
|
|
130
|
+
2. Process queue, attempt send
|
|
131
|
+
3. On success: mark "sent", store message ID
|
|
132
|
+
4. On retryable failure: increment retry count, schedule retry
|
|
133
|
+
5. On permanent failure: mark "failed", alert
|
|
134
|
+
|
|
135
|
+
## Timeouts
|
|
136
|
+
|
|
137
|
+
Set appropriate timeouts to avoid hanging requests.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
const controller = new AbortController();
|
|
141
|
+
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
await resend.emails.send(emailData, { signal: controller.signal });
|
|
145
|
+
} finally {
|
|
146
|
+
clearTimeout(timeout);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Recommended:** 10-30 seconds for email API calls.
|
|
151
|
+
|
|
152
|
+
## Related
|
|
153
|
+
|
|
154
|
+
- [Webhooks & Events](./webhooks-events.md) - Process delivery confirmations and failures
|
|
155
|
+
- [List Management](./list-management.md) - Handle bounces and suppress invalid addresses
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# Transactional Email Catalog
|
|
2
|
+
|
|
3
|
+
A comprehensive catalog of transactional emails organized by category, plus recommended email combinations for different app types.
|
|
4
|
+
|
|
5
|
+
## When to Use This
|
|
6
|
+
|
|
7
|
+
- Planning what transactional emails your app needs
|
|
8
|
+
- Choosing the right emails for your app type
|
|
9
|
+
- Understanding what content each email type should include
|
|
10
|
+
- Implementing transactional email features
|
|
11
|
+
|
|
12
|
+
## Email Combinations by App Type
|
|
13
|
+
|
|
14
|
+
Use these combinations as a starting point based on what you're building.
|
|
15
|
+
|
|
16
|
+
### Authentication-Focused App
|
|
17
|
+
|
|
18
|
+
Apps where user accounts and security are core (login systems, identity providers, account management).
|
|
19
|
+
|
|
20
|
+
**Essential:**
|
|
21
|
+
- Email verification
|
|
22
|
+
- Password reset
|
|
23
|
+
- OTP / 2FA codes
|
|
24
|
+
- Security alerts (new device, password change)
|
|
25
|
+
- Account update notifications
|
|
26
|
+
|
|
27
|
+
**Optional:**
|
|
28
|
+
- Welcome email (must not be promotional)
|
|
29
|
+
- Account deletion confirmation
|
|
30
|
+
|
|
31
|
+
### Newsletter / Content Platform
|
|
32
|
+
|
|
33
|
+
Apps focused on content delivery and subscriptions.
|
|
34
|
+
|
|
35
|
+
**Essential:**
|
|
36
|
+
- Email verification
|
|
37
|
+
- Password reset
|
|
38
|
+
- Welcome email (must not be promotional)
|
|
39
|
+
- Subscription confirmation
|
|
40
|
+
|
|
41
|
+
**Optional:**
|
|
42
|
+
- OTP / 2FA codes
|
|
43
|
+
- Account update notifications
|
|
44
|
+
|
|
45
|
+
### E-commerce / Marketplace
|
|
46
|
+
|
|
47
|
+
Apps where users buy products or services.
|
|
48
|
+
|
|
49
|
+
**Essential:**
|
|
50
|
+
- Email verification
|
|
51
|
+
- Password reset
|
|
52
|
+
- Welcome email (must not be promotional)
|
|
53
|
+
- Order confirmation
|
|
54
|
+
- Shipping notifications
|
|
55
|
+
- Invoice / receipt
|
|
56
|
+
- Payment failed notices
|
|
57
|
+
|
|
58
|
+
**Optional:**
|
|
59
|
+
- OTP / 2FA codes
|
|
60
|
+
- Security alerts
|
|
61
|
+
- Subscription confirmations (for recurring orders)
|
|
62
|
+
|
|
63
|
+
### SaaS / Subscription Service
|
|
64
|
+
|
|
65
|
+
Apps with paid subscription tiers and ongoing billing.
|
|
66
|
+
|
|
67
|
+
**Essential:**
|
|
68
|
+
- Email verification
|
|
69
|
+
- Password reset
|
|
70
|
+
- Welcome email (must not be promotional)
|
|
71
|
+
- OTP / 2FA codes
|
|
72
|
+
- Security alerts
|
|
73
|
+
- Subscription confirmation
|
|
74
|
+
- Subscription renewal notice
|
|
75
|
+
- Payment failed notices
|
|
76
|
+
- Invoice / receipt
|
|
77
|
+
|
|
78
|
+
**Optional:**
|
|
79
|
+
- Account update notifications
|
|
80
|
+
- Feature change notifications (for breaking changes)
|
|
81
|
+
|
|
82
|
+
### Financial / Fintech App
|
|
83
|
+
|
|
84
|
+
Apps handling money, payments, or sensitive financial data.
|
|
85
|
+
|
|
86
|
+
**Essential:**
|
|
87
|
+
- Email verification
|
|
88
|
+
- Password reset
|
|
89
|
+
- OTP / 2FA codes (required for sensitive actions)
|
|
90
|
+
- Security alerts (all types)
|
|
91
|
+
- Account update notifications
|
|
92
|
+
- Transaction confirmations
|
|
93
|
+
- Invoice / receipt
|
|
94
|
+
- Payment failed notices
|
|
95
|
+
|
|
96
|
+
**Optional:**
|
|
97
|
+
- Welcome email (must not be promotional)
|
|
98
|
+
- Compliance notices
|
|
99
|
+
|
|
100
|
+
### Social / Community Platform
|
|
101
|
+
|
|
102
|
+
Apps focused on user interaction and community features.
|
|
103
|
+
|
|
104
|
+
**Essential:**
|
|
105
|
+
- Email verification
|
|
106
|
+
- Password reset
|
|
107
|
+
- Welcome email (must not be promotional)
|
|
108
|
+
- Security alerts
|
|
109
|
+
|
|
110
|
+
**Optional:**
|
|
111
|
+
- OTP / 2FA codes
|
|
112
|
+
- Account update notifications
|
|
113
|
+
- Activity notifications (mentions, replies)
|
|
114
|
+
|
|
115
|
+
### Developer Tools / API Platform
|
|
116
|
+
|
|
117
|
+
Apps targeting developers with API access and integrations.
|
|
118
|
+
|
|
119
|
+
**Essential:**
|
|
120
|
+
- Email verification
|
|
121
|
+
- Password reset
|
|
122
|
+
- OTP / 2FA codes
|
|
123
|
+
- Security alerts
|
|
124
|
+
- API key notifications (creation, expiration)
|
|
125
|
+
- Subscription confirmation
|
|
126
|
+
- Payment failed notices
|
|
127
|
+
|
|
128
|
+
**Optional:**
|
|
129
|
+
- Welcome email (must not be promotional)
|
|
130
|
+
- Usage alerts (approaching limits)
|
|
131
|
+
- Feature change notifications
|
|
132
|
+
|
|
133
|
+
### Healthcare / HIPAA-Compliant App
|
|
134
|
+
|
|
135
|
+
Apps handling protected health information.
|
|
136
|
+
|
|
137
|
+
**Essential:**
|
|
138
|
+
- Email verification
|
|
139
|
+
- Password reset
|
|
140
|
+
- OTP / 2FA codes (required)
|
|
141
|
+
- Security alerts (all types, detailed)
|
|
142
|
+
- Account update notifications
|
|
143
|
+
- Appointment confirmations
|
|
144
|
+
|
|
145
|
+
**Optional:**
|
|
146
|
+
- Welcome email (must not be promotional)
|
|
147
|
+
- Compliance notices
|
|
148
|
+
|
|
149
|
+
**Note:** Healthcare apps have strict requirements. Emails should contain minimal PHI and link to secure portals for sensitive information.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Full Email Catalog
|
|
154
|
+
|
|
155
|
+
### Authentication & Security
|
|
156
|
+
|
|
157
|
+
#### Email Verification / Account Verification
|
|
158
|
+
|
|
159
|
+
**When to send:** Immediately after user signs up or changes email address.
|
|
160
|
+
|
|
161
|
+
**Purpose:** Verify the email address belongs to the user.
|
|
162
|
+
|
|
163
|
+
**Content should include:**
|
|
164
|
+
- Clear verification link or code
|
|
165
|
+
- Expiration time (typically 24-48 hours)
|
|
166
|
+
- Instructions on what to do
|
|
167
|
+
- Security notice if link is clicked by mistake
|
|
168
|
+
|
|
169
|
+
**Best practices:**
|
|
170
|
+
- Send immediately (within seconds)
|
|
171
|
+
- Include expiration notice
|
|
172
|
+
- Provide resend option
|
|
173
|
+
- Link to support if issues
|
|
174
|
+
|
|
175
|
+
#### OTP / 2FA Codes
|
|
176
|
+
|
|
177
|
+
**When to send:** When user requests two-factor authentication code.
|
|
178
|
+
|
|
179
|
+
**Purpose:** Provide time-sensitive authentication code.
|
|
180
|
+
|
|
181
|
+
**Content should include:**
|
|
182
|
+
- The OTP code (clearly displayed)
|
|
183
|
+
- Expiration time (typically 5-10 minutes)
|
|
184
|
+
- Security warnings
|
|
185
|
+
- Instructions on what to do if not requested
|
|
186
|
+
|
|
187
|
+
**Best practices:**
|
|
188
|
+
- Send immediately
|
|
189
|
+
- Code should be large and easy to read
|
|
190
|
+
- Include expiration prominently
|
|
191
|
+
- Warn about sharing codes
|
|
192
|
+
- Provide "I didn't request this" link
|
|
193
|
+
|
|
194
|
+
#### Password Reset
|
|
195
|
+
|
|
196
|
+
**When to send:** When user requests password reset.
|
|
197
|
+
|
|
198
|
+
**Purpose:** Allow user to securely reset forgotten password.
|
|
199
|
+
|
|
200
|
+
**Content should include:**
|
|
201
|
+
- Reset link (with token)
|
|
202
|
+
- Expiration time (typically 1 hour)
|
|
203
|
+
- Security warnings
|
|
204
|
+
- Instructions if not requested
|
|
205
|
+
|
|
206
|
+
**Best practices:**
|
|
207
|
+
- Send immediately
|
|
208
|
+
- Link expires quickly (1 hour)
|
|
209
|
+
- Include IP address and location if available
|
|
210
|
+
- Provide "I didn't request this" link
|
|
211
|
+
- Don't include the old password
|
|
212
|
+
|
|
213
|
+
#### Security Alerts
|
|
214
|
+
|
|
215
|
+
**When to send:** When security-relevant events occur (login from new device, password change, etc.).
|
|
216
|
+
|
|
217
|
+
**Purpose:** Notify user of account security events.
|
|
218
|
+
|
|
219
|
+
**Content should include:**
|
|
220
|
+
- What happened (clear description)
|
|
221
|
+
- When it happened
|
|
222
|
+
- Location/IP if available
|
|
223
|
+
- Action to take if suspicious
|
|
224
|
+
- Link to security settings
|
|
225
|
+
|
|
226
|
+
**Best practices:**
|
|
227
|
+
- Send immediately
|
|
228
|
+
- Be clear and specific
|
|
229
|
+
- Include actionable steps
|
|
230
|
+
- Provide way to report suspicious activity
|
|
231
|
+
|
|
232
|
+
### Account Management
|
|
233
|
+
|
|
234
|
+
#### Welcome Email
|
|
235
|
+
|
|
236
|
+
**When to send:** Immediately after successful account creation and verification.
|
|
237
|
+
|
|
238
|
+
**Purpose:** Welcome new users and guide them to next steps (must not be promotional).
|
|
239
|
+
|
|
240
|
+
**Content should include:**
|
|
241
|
+
- Welcome message
|
|
242
|
+
- Key features or next steps
|
|
243
|
+
- Links to important resources
|
|
244
|
+
- Support contact information
|
|
245
|
+
|
|
246
|
+
**Best practices:**
|
|
247
|
+
- Send after email verification
|
|
248
|
+
- Keep it focused and actionable
|
|
249
|
+
- Don't overwhelm with information
|
|
250
|
+
- Set expectations about future emails
|
|
251
|
+
|
|
252
|
+
#### Account Update Notifications
|
|
253
|
+
|
|
254
|
+
**When to send:** When user changes account settings (email, password, profile, etc.).
|
|
255
|
+
|
|
256
|
+
**Purpose:** Confirm account changes and provide security notice.
|
|
257
|
+
|
|
258
|
+
**Content should include:**
|
|
259
|
+
- What changed
|
|
260
|
+
- When it changed
|
|
261
|
+
- Action to take if unauthorized
|
|
262
|
+
- Link to account settings
|
|
263
|
+
|
|
264
|
+
**Best practices:**
|
|
265
|
+
- Send immediately after change
|
|
266
|
+
- Be specific about what changed
|
|
267
|
+
- Include security notice
|
|
268
|
+
- Provide easy way to revert if needed
|
|
269
|
+
|
|
270
|
+
### E-commerce & Transactions
|
|
271
|
+
|
|
272
|
+
#### Order Confirmations
|
|
273
|
+
|
|
274
|
+
**When to send:** Immediately after order is placed.
|
|
275
|
+
|
|
276
|
+
**Purpose:** Confirm order details and provide receipt.
|
|
277
|
+
|
|
278
|
+
**Content should include:**
|
|
279
|
+
- Order number
|
|
280
|
+
- Items ordered with quantities
|
|
281
|
+
- Pricing breakdown
|
|
282
|
+
- Shipping address
|
|
283
|
+
- Estimated delivery date
|
|
284
|
+
- Order tracking link (if available)
|
|
285
|
+
|
|
286
|
+
**Best practices:**
|
|
287
|
+
- Send within minutes of order
|
|
288
|
+
- Include all order details
|
|
289
|
+
- Make it easy to print or save
|
|
290
|
+
- Provide customer service contact
|
|
291
|
+
|
|
292
|
+
#### Shipping Notifications
|
|
293
|
+
|
|
294
|
+
**When to send:** When order ships, with tracking updates.
|
|
295
|
+
|
|
296
|
+
**Purpose:** Notify user that order has shipped and provide tracking.
|
|
297
|
+
|
|
298
|
+
**Content should include:**
|
|
299
|
+
- Order number
|
|
300
|
+
- Tracking number
|
|
301
|
+
- Carrier information
|
|
302
|
+
- Expected delivery date
|
|
303
|
+
- Tracking link
|
|
304
|
+
- Shipping address confirmation
|
|
305
|
+
|
|
306
|
+
**Best practices:**
|
|
307
|
+
- Send when order ships
|
|
308
|
+
- Include tracking number prominently
|
|
309
|
+
- Provide carrier tracking link
|
|
310
|
+
- Update on major tracking milestones
|
|
311
|
+
|
|
312
|
+
#### Invoices and Receipts
|
|
313
|
+
|
|
314
|
+
**When to send:** After payment is processed.
|
|
315
|
+
|
|
316
|
+
**Purpose:** Provide payment confirmation and receipt.
|
|
317
|
+
|
|
318
|
+
**Content should include:**
|
|
319
|
+
- Invoice/receipt number
|
|
320
|
+
- Payment amount
|
|
321
|
+
- Payment method
|
|
322
|
+
- Items/services purchased
|
|
323
|
+
- Payment date
|
|
324
|
+
- Downloadable PDF (if applicable)
|
|
325
|
+
|
|
326
|
+
**Best practices:**
|
|
327
|
+
- Send immediately after payment
|
|
328
|
+
- Include all payment details
|
|
329
|
+
- Make it easy to download/save
|
|
330
|
+
- Include tax information if applicable
|
|
331
|
+
|
|
332
|
+
### Subscriptions & Billing
|
|
333
|
+
|
|
334
|
+
#### Subscription Confirmations
|
|
335
|
+
|
|
336
|
+
**When to send:** When user subscribes or changes subscription.
|
|
337
|
+
|
|
338
|
+
**Purpose:** Confirm subscription details and billing information.
|
|
339
|
+
|
|
340
|
+
**Content should include:**
|
|
341
|
+
- Subscription plan details
|
|
342
|
+
- Billing amount and frequency
|
|
343
|
+
- Next billing date
|
|
344
|
+
- Payment method
|
|
345
|
+
- Link to manage subscription
|
|
346
|
+
|
|
347
|
+
**Best practices:**
|
|
348
|
+
- Send immediately after subscription
|
|
349
|
+
- Clearly state billing terms
|
|
350
|
+
- Provide easy cancellation option
|
|
351
|
+
- Include support contact
|
|
352
|
+
|
|
353
|
+
#### Subscription Renewal Notices
|
|
354
|
+
|
|
355
|
+
**When to send:** Before subscription renews (typically 3-7 days before).
|
|
356
|
+
|
|
357
|
+
**Purpose:** Notify user of upcoming renewal and charge.
|
|
358
|
+
|
|
359
|
+
**Content should include:**
|
|
360
|
+
- Renewal date
|
|
361
|
+
- Amount to be charged
|
|
362
|
+
- Payment method on file
|
|
363
|
+
- Link to update payment method
|
|
364
|
+
- Link to cancel if desired
|
|
365
|
+
|
|
366
|
+
**Best practices:**
|
|
367
|
+
- Send with enough notice (3-7 days)
|
|
368
|
+
- Be clear about amount and date
|
|
369
|
+
- Make it easy to update payment method
|
|
370
|
+
- Provide cancellation option
|
|
371
|
+
|
|
372
|
+
#### Payment Failed Notices
|
|
373
|
+
|
|
374
|
+
**When to send:** When subscription payment fails.
|
|
375
|
+
|
|
376
|
+
**Purpose:** Notify user of payment failure and provide resolution steps.
|
|
377
|
+
|
|
378
|
+
**Content should include:**
|
|
379
|
+
- What happened
|
|
380
|
+
- Amount that failed
|
|
381
|
+
- Reason for failure (if available)
|
|
382
|
+
- Steps to resolve
|
|
383
|
+
- Link to update payment method
|
|
384
|
+
- Consequences if not resolved
|
|
385
|
+
|
|
386
|
+
**Best practices:**
|
|
387
|
+
- Send immediately after failure
|
|
388
|
+
- Be clear about consequences
|
|
389
|
+
- Provide easy resolution path
|
|
390
|
+
- Include support contact
|
|
391
|
+
|
|
392
|
+
### Notifications & Updates
|
|
393
|
+
|
|
394
|
+
#### Feature Announcements (Transactional)
|
|
395
|
+
|
|
396
|
+
**When to send:** When a feature the user is using changes significantly.
|
|
397
|
+
|
|
398
|
+
**Purpose:** Notify users of changes that affect their use of the service.
|
|
399
|
+
|
|
400
|
+
**Content should include:**
|
|
401
|
+
- What changed
|
|
402
|
+
- How it affects the user
|
|
403
|
+
- What action (if any) is needed
|
|
404
|
+
- Link to more information
|
|
405
|
+
|
|
406
|
+
**Best practices:**
|
|
407
|
+
- Only for significant changes
|
|
408
|
+
- Focus on user impact
|
|
409
|
+
- Provide clear next steps
|
|
410
|
+
- Link to documentation
|
|
411
|
+
|
|
412
|
+
**Note:** General feature announcements are marketing emails. Only send as transactional if the change directly affects an active feature the user is using.
|
|
413
|
+
|
|
414
|
+
## Related Topics
|
|
415
|
+
|
|
416
|
+
- [Email Types](./email-types.md) - Understanding transactional vs marketing
|
|
417
|
+
- [Transactional Emails](./transactional-emails.md) - Best practices for sending transactional emails
|
|
418
|
+
- [Compliance](./compliance.md) - Legal requirements for each email type
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Transactional Email Best Practices
|
|
2
|
+
|
|
3
|
+
Clear, actionable emails that users expect and need—password resets, confirmations, OTPs.
|
|
4
|
+
|
|
5
|
+
## Core Principles
|
|
6
|
+
|
|
7
|
+
1. **Clarity over creativity** - Users need to understand and act quickly
|
|
8
|
+
2. **Action-oriented** - Clear purpose, obvious primary action
|
|
9
|
+
3. **Time-sensitive** - Send immediately (within seconds)
|
|
10
|
+
|
|
11
|
+
## Subject Lines
|
|
12
|
+
|
|
13
|
+
**Be specific and include context:**
|
|
14
|
+
|
|
15
|
+
| ✅ Good | ❌ Bad |
|
|
16
|
+
|---------|--------|
|
|
17
|
+
| Reset your password for [App] | Action required |
|
|
18
|
+
| Your order #12345 has shipped | Update on your order |
|
|
19
|
+
| Your 2FA code for [App] | Security code: 12345 |
|
|
20
|
+
| Verify your email for [App] | Verify your email |
|
|
21
|
+
|
|
22
|
+
Include identifiers when helpful: order numbers, account names, expiration times.
|
|
23
|
+
|
|
24
|
+
## Pre-Header
|
|
25
|
+
|
|
26
|
+
The text snippet after subject line. Use it to:
|
|
27
|
+
- Reinforce subject ("This link expires in 1 hour")
|
|
28
|
+
- Add urgency or context
|
|
29
|
+
- Call-to-action preview
|
|
30
|
+
|
|
31
|
+
Keep under 90 characters.
|
|
32
|
+
|
|
33
|
+
## Content Structure
|
|
34
|
+
|
|
35
|
+
**Above the fold (first screen):**
|
|
36
|
+
- Clear purpose
|
|
37
|
+
- Primary action button
|
|
38
|
+
- Time-sensitive details (expiration)
|
|
39
|
+
|
|
40
|
+
**Hierarchy:** Header → Primary message → Details → Action button → Secondary info
|
|
41
|
+
|
|
42
|
+
**Format:** Short paragraphs (2-3 sentences), bullet points, bold for emphasis, white space.
|
|
43
|
+
|
|
44
|
+
## Mobile-First Design
|
|
45
|
+
|
|
46
|
+
60%+ emails are opened on mobile.
|
|
47
|
+
|
|
48
|
+
- **Layout:** Single column, stack vertically
|
|
49
|
+
- **Buttons:** 44x44px minimum, full-width on mobile
|
|
50
|
+
- **Text:** 16px minimum body, 20-24px headings
|
|
51
|
+
- **OTP codes:** 24-32px, monospace font
|
|
52
|
+
|
|
53
|
+
## Sender Configuration
|
|
54
|
+
|
|
55
|
+
| Field | Best Practice | Example |
|
|
56
|
+
|-------|--------------|---------|
|
|
57
|
+
| From Name | App/company name, consistent | [App Name] |
|
|
58
|
+
| From Email | Subdomain, real address | hello@mail.example.com |
|
|
59
|
+
| Reply-To | Monitored inbox | support@example.com |
|
|
60
|
+
|
|
61
|
+
Avoid `noreply@` - users reply to transactional emails.
|
|
62
|
+
|
|
63
|
+
## Code and Link Display
|
|
64
|
+
|
|
65
|
+
**OTP/Verification codes:**
|
|
66
|
+
- Large (24-32px), monospace font
|
|
67
|
+
- Centered, clear label
|
|
68
|
+
- Include expiration nearby
|
|
69
|
+
- Make copyable
|
|
70
|
+
|
|
71
|
+
**Buttons:**
|
|
72
|
+
- Large, tappable (44x44px+)
|
|
73
|
+
- Contrasting colors
|
|
74
|
+
- Clear action text ("Reset Password", "Verify Email")
|
|
75
|
+
- HTTPS links only
|
|
76
|
+
|
|
77
|
+
## Error Handling
|
|
78
|
+
|
|
79
|
+
**Resend functionality:**
|
|
80
|
+
- Allow after 60 seconds
|
|
81
|
+
- Limit attempts (3 per hour)
|
|
82
|
+
- Show countdown timer
|
|
83
|
+
|
|
84
|
+
**Expired links:**
|
|
85
|
+
- Clear "expired" message
|
|
86
|
+
- Offer to send new link
|
|
87
|
+
- Provide support contact
|
|
88
|
+
|
|
89
|
+
**"I didn't request this":**
|
|
90
|
+
- Include in password resets, OTPs, security alerts
|
|
91
|
+
- Link to security contact
|
|
92
|
+
- Log clicks for monitoring
|