Account-level sending statistics, quotas, and monitoring capabilities for tracking email performance and compliance. This module provides comprehensive insights into your email sending activity and account limits.
Monitor and manage your SES sending limits.
/**
* Gets your current sending quota information
* @param input - Empty input
* @returns Promise with quota details
*/
interface GetSendQuotaCommandInput {}
interface GetSendQuotaCommandOutput {
/** Maximum emails you can send in 24 hours */
Max24HourSend?: number;
/** Maximum emails per second you can send */
MaxSendRate?: number;
/** Emails sent in the last 24 hours */
SentLast24Hours?: number;
$metadata: ResponseMetadata;
}Usage Example:
import { SESClient, GetSendQuotaCommand } from "@aws-sdk/client-ses";
const client = new SESClient({ region: "us-east-1" });
const quotaCommand = new GetSendQuotaCommand({});
const quota = await client.send(quotaCommand);
console.log("Daily quota:", quota.Max24HourSend);
console.log("Rate limit:", quota.MaxSendRate, "emails/second");
console.log("Sent today:", quota.SentLast24Hours);
// Calculate remaining quota
const remaining = (quota.Max24HourSend || 0) - (quota.SentLast24Hours || 0);
console.log("Remaining today:", remaining);
// Check if near rate limit
if (quota.SentLast24Hours && quota.Max24HourSend) {
const usage = (quota.SentLast24Hours / quota.Max24HourSend) * 100;
if (usage > 80) {
console.warn(`High quota usage: ${usage.toFixed(1)}%`);
}
}Retrieve detailed sending statistics and performance metrics.
/**
* Gets sending statistics for your account
* @param input - Empty input
* @returns Promise with sending statistics
*/
interface GetSendStatisticsCommandInput {}
interface GetSendStatisticsCommandOutput {
/** List of sending data points */
SendDataPoints?: SendDataPoint[];
$metadata: ResponseMetadata;
}
interface SendDataPoint {
/** Timestamp for this data point */
Timestamp?: Date;
/** Number of delivery attempts */
DeliveryAttempts?: number;
/** Number of bounced emails */
Bounces?: number;
/** Number of complaint reports */
Complaints?: number;
/** Number of rejected emails */
Rejects?: number;
}Usage Example:
import { SESClient, GetSendStatisticsCommand } from "@aws-sdk/client-ses";
const client = new SESClient({ region: "us-east-1" });
const statsCommand = new GetSendStatisticsCommand({});
const stats = await client.send(statsCommand);
console.log("Recent sending statistics:");
stats.SendDataPoints?.forEach((point, index) => {
const timestamp = point.Timestamp?.toISOString();
const deliveryRate = point.DeliveryAttempts ?
((point.DeliveryAttempts - (point.Bounces || 0)) / point.DeliveryAttempts * 100).toFixed(2) : 0;
const bounceRate = point.DeliveryAttempts ?
((point.Bounces || 0) / point.DeliveryAttempts * 100).toFixed(2) : 0;
const complaintRate = point.DeliveryAttempts ?
((point.Complaints || 0) / point.DeliveryAttempts * 100).toFixed(2) : 0;
console.log(`${timestamp}:`);
console.log(` Attempts: ${point.DeliveryAttempts}`);
console.log(` Delivery Rate: ${deliveryRate}%`);
console.log(` Bounce Rate: ${bounceRate}%`);
console.log(` Complaint Rate: ${complaintRate}%`);
console.log(` Rejects: ${point.Rejects}`);
});
// Calculate overall metrics
const totals = stats.SendDataPoints?.reduce((acc, point) => ({
attempts: acc.attempts + (point.DeliveryAttempts || 0),
bounces: acc.bounces + (point.Bounces || 0),
complaints: acc.complaints + (point.Complaints || 0),
rejects: acc.rejects + (point.Rejects || 0),
}), { attempts: 0, bounces: 0, complaints: 0, rejects: 0 });
if (totals && totals.attempts > 0) {
console.log("\nOverall Statistics:");
console.log(`Total Attempts: ${totals.attempts}`);
console.log(`Overall Bounce Rate: ${(totals.bounces / totals.attempts * 100).toFixed(2)}%`);
console.log(`Overall Complaint Rate: ${(totals.complaints / totals.attempts * 100).toFixed(2)}%`);
// Alert on high bounce/complaint rates
const bounceRate = totals.bounces / totals.attempts;
const complaintRate = totals.complaints / totals.attempts;
if (bounceRate > 0.05) {
console.warn("⚠️ High bounce rate detected (>5%)");
}
if (complaintRate > 0.001) {
console.warn("⚠️ High complaint rate detected (>0.1%)");
}
}Check and manage account-level sending permissions.
/**
* Checks if sending is enabled for your account
* @param input - Empty input
* @returns Promise with sending status
*/
interface GetAccountSendingEnabledCommandInput {}
interface GetAccountSendingEnabledCommandOutput {
/** Whether sending is enabled for the account */
Enabled?: boolean;
$metadata: ResponseMetadata;
}
/**
* Enables or disables sending for your entire account
* @param input - Enabled status
* @returns Promise with operation result
*/
interface UpdateAccountSendingEnabledCommandInput {
/** Whether to enable sending */
Enabled?: boolean;
}
interface UpdateAccountSendingEnabledCommandOutput {
$metadata: ResponseMetadata;
}Usage Example:
import {
SESClient,
GetAccountSendingEnabledCommand,
UpdateAccountSendingEnabledCommand
} from "@aws-sdk/client-ses";
const client = new SESClient({ region: "us-east-1" });
// Check current sending status
const statusCommand = new GetAccountSendingEnabledCommand({});
const status = await client.send(statusCommand);
console.log("Account sending enabled:", status.Enabled);
if (!status.Enabled) {
console.log("Sending is disabled for this account");
// Enable sending (use with caution)
const enableCommand = new UpdateAccountSendingEnabledCommand({
Enabled: true,
});
await client.send(enableCommand);
console.log("Account sending has been enabled");
}
// Disable sending (emergency use)
// const disableCommand = new UpdateAccountSendingEnabledCommand({
// Enabled: false,
// });
// await client.send(disableCommand);Utility functions for monitoring quota usage and setting up alerts.
// Example utility functions (not part of AWS SDK)
interface QuotaMonitoringOptions {
warningThreshold: number; // Percentage (0-100)
criticalThreshold: number; // Percentage (0-100)
}
async function monitorQuotaUsage(
client: SESClient,
options: QuotaMonitoringOptions = { warningThreshold: 80, criticalThreshold: 95 }
) {
const quota = await client.send(new GetSendQuotaCommand({}));
if (!quota.Max24HourSend || !quota.SentLast24Hours) {
return { status: "unknown", usage: 0 };
}
const usagePercent = (quota.SentLast24Hours / quota.Max24HourSend) * 100;
let status = "normal";
if (usagePercent >= options.criticalThreshold) {
status = "critical";
} else if (usagePercent >= options.warningThreshold) {
status = "warning";
}
return {
status,
usage: usagePercent,
sent: quota.SentLast24Hours,
limit: quota.Max24HourSend,
remaining: quota.Max24HourSend - quota.SentLast24Hours,
maxRate: quota.MaxSendRate,
};
}
// Usage
const monitor = await monitorQuotaUsage(client);
console.log(`Quota usage: ${monitor.usage.toFixed(1)}% (${monitor.status})`);Analyze sending performance trends and identify issues.
// Example analytics utility (not part of AWS SDK)
interface PerformanceMetrics {
period: string;
totalAttempts: number;
deliveryRate: number;
bounceRate: number;
complaintRate: number;
rejectRate: number;
trend: "improving" | "declining" | "stable";
}
async function analyzePerformance(client: SESClient): Promise<PerformanceMetrics[]> {
const stats = await client.send(new GetSendStatisticsCommand({}));
if (!stats.SendDataPoints || stats.SendDataPoints.length === 0) {
return [];
}
// Group by day for daily metrics
const dailyMetrics = new Map<string, SendDataPoint[]>();
stats.SendDataPoints.forEach(point => {
if (point.Timestamp) {
const day = point.Timestamp.toISOString().split('T')[0];
if (!dailyMetrics.has(day)) {
dailyMetrics.set(day, []);
}
dailyMetrics.get(day)!.push(point);
}
});
const results: PerformanceMetrics[] = [];
for (const [day, points] of dailyMetrics) {
const totals = points.reduce((acc, point) => ({
attempts: acc.attempts + (point.DeliveryAttempts || 0),
bounces: acc.bounces + (point.Bounces || 0),
complaints: acc.complaints + (point.Complaints || 0),
rejects: acc.rejects + (point.Rejects || 0),
}), { attempts: 0, bounces: 0, complaints: 0, rejects: 0 });
if (totals.attempts > 0) {
results.push({
period: day,
totalAttempts: totals.attempts,
deliveryRate: ((totals.attempts - totals.bounces) / totals.attempts) * 100,
bounceRate: (totals.bounces / totals.attempts) * 100,
complaintRate: (totals.complaints / totals.attempts) * 100,
rejectRate: (totals.rejects / totals.attempts) * 100,
trend: "stable", // Could be calculated by comparing to previous periods
});
}
}
return results.sort((a, b) => a.period.localeCompare(b.period));
}
// Usage
const performance = await analyzePerformance(client);
performance.forEach(metric => {
console.log(`${metric.period}:`);
console.log(` Delivery Rate: ${metric.deliveryRate.toFixed(2)}%`);
console.log(` Bounce Rate: ${metric.bounceRate.toFixed(2)}%`);
console.log(` Complaint Rate: ${metric.complaintRate.toFixed(2)}%`);
});class AccountSendingPausedException extends SESServiceException {
name: "AccountSendingPausedException";
}
class ProductionAccessNotGrantedException extends SESServiceException {
name: "ProductionAccessNotGrantedException";
}import {
SESClient,
GetSendQuotaCommand,
GetSendStatisticsCommand,
GetAccountSendingEnabledCommand
} from "@aws-sdk/client-ses";
const client = new SESClient({ region: "us-east-1" });
async function generateDashboard() {
console.log("=== SES Account Dashboard ===\n");
// 1. Account Status
const accountStatus = await client.send(new GetAccountSendingEnabledCommand({}));
console.log("📊 Account Status");
console.log(`Sending Enabled: ${accountStatus.Enabled ? "✅ Yes" : "❌ No"}`);
// 2. Quota Information
const quota = await client.send(new GetSendQuotaCommand({}));
console.log("\n📈 Sending Quota");
console.log(`Daily Limit: ${quota.Max24HourSend?.toLocaleString()} emails`);
console.log(`Rate Limit: ${quota.MaxSendRate} emails/second`);
console.log(`Sent Today: ${quota.SentLast24Hours?.toLocaleString()} emails`);
if (quota.Max24HourSend && quota.SentLast24Hours) {
const remaining = quota.Max24HourSend - quota.SentLast24Hours;
const usagePercent = (quota.SentLast24Hours / quota.Max24HourSend) * 100;
console.log(`Remaining: ${remaining.toLocaleString()} emails`);
console.log(`Usage: ${usagePercent.toFixed(1)}%`);
if (usagePercent > 90) {
console.log("⚠️ Critical: Near quota limit!");
} else if (usagePercent > 75) {
console.log("⚠️ Warning: High quota usage");
}
}
// 3. Recent Statistics
const stats = await client.send(new GetSendStatisticsCommand({}));
console.log("\n📊 Recent Performance");
if (stats.SendDataPoints && stats.SendDataPoints.length > 0) {
const recent = stats.SendDataPoints
.filter(point => point.Timestamp)
.sort((a, b) => b.Timestamp!.getTime() - a.Timestamp!.getTime())
.slice(0, 5);
console.log("Last 5 data points:");
recent.forEach(point => {
const time = point.Timestamp?.toLocaleString();
const deliveryRate = point.DeliveryAttempts ?
((point.DeliveryAttempts - (point.Bounces || 0)) / point.DeliveryAttempts * 100) : 0;
console.log(` ${time}: ${point.DeliveryAttempts} attempts, ${deliveryRate.toFixed(1)}% delivered`);
});
// Overall health check
const totals = stats.SendDataPoints.reduce((acc, point) => ({
attempts: acc.attempts + (point.DeliveryAttempts || 0),
bounces: acc.bounces + (point.Bounces || 0),
complaints: acc.complaints + (point.Complaints || 0),
}), { attempts: 0, bounces: 0, complaints: 0 });
if (totals.attempts > 0) {
const bounceRate = (totals.bounces / totals.attempts) * 100;
const complaintRate = (totals.complaints / totals.attempts) * 100;
console.log("\n🏥 Health Check");
console.log(`Bounce Rate: ${bounceRate.toFixed(3)}% ${bounceRate > 5 ? "❌ HIGH" : "✅ OK"}`);
console.log(`Complaint Rate: ${complaintRate.toFixed(3)}% ${complaintRate > 0.1 ? "❌ HIGH" : "✅ OK"}`);
}
} else {
console.log("No recent statistics available");
}
}
// Run dashboard
generateDashboard().catch(console.error);