{"id":252655,"date":"2025-12-29T09:49:58","date_gmt":"2025-12-29T09:49:58","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/api-mailer-for-aws-ses\/"},"modified":"2026-02-26T09:54:25","modified_gmt":"2026-02-26T09:54:25","slug":"api-mailer-for-aws-ses","status":"publish","type":"plugin","link":"https:\/\/azb.wordpress.org\/plugins\/api-mailer-for-aws-ses\/","author":23461136,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.4","stable_tag":"1.4","tested":"6.9.4","requires":"5.6","requires_php":"7.4","requires_plugins":null,"header_name":"API Mailer for AWS SES","header_author":"beltoft.net","header_description":"Fast, lightweight WordPress mailer that sends via Amazon SES SendRawEmail API (no SMTP). Includes background queue, logging, and wp-config credentials.","assets_banners_color":"","last_updated":"2026-02-26 09:54:25","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/beltoft.net","rating":5,"author_block_rating":0,"active_installs":0,"downloads":272,"num_ratings":1,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1":{"tag":"1.1","author":"christian198521","date":"2025-12-29 09:54:28"},"1.3":{"tag":"1.3","author":"christian198521","date":"2026-02-13 13:01:59"},"1.4":{"tag":"1.4","author":"christian198521","date":"2026-02-26 09:54:25"}},"upgrade_notice":{"1.4":"<p>Logging moved to WooCommerce logger \/ error_log. The <code>wp-content\/ses-mailer-logs\/<\/code> folder is no longer used and can be safely deleted after upgrading.<\/p>","1.0.0":"<p>Initial release. Configure credentials and test your SES connection on the Status tab before enabling in production.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":1},"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1","1.3","1.4"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Settings screen with credential and queue options","2":"Test tab to send a test email","3":"Status tab showing SES send quotas"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[1556,1898,267,9965,6929],"plugin_category":[41],"plugin_contributors":[256640],"plugin_business_model":[],"class_list":["post-252655","plugin","type-plugin","status-publish","hentry","plugin_tags-api","plugin_tags-aws","plugin_tags-email","plugin_tags-mailer","plugin_tags-ses","plugin_category-communication","plugin_contributors-beltoftnet","plugin_committers-beltoftnet","plugin_committers-christian198521"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/api-mailer-for-aws-ses.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>API Mailer for AWS SES replaces <code>wp_mail()<\/code> with a direct Amazon SES API integration (SendRawEmail). There is no SMTP layer or PHPMailer handoff in the critical path, reducing overhead and improving reliability.<\/p>\n\n<p>The plugin focuses on correctness, performance, and operational clarity:\n- Direct AWS SigV4 signed requests to SES\n- Minimal overhead in the <code>wp_mail()<\/code> hook\n- Optional background queue with Action Scheduler or wp_cron fallback\n- Optional logging via WooCommerce logger or PHP error_log\n- Clean, PSR-4 structured codebase<\/p>\n\n<h3>Key Features<\/h3>\n\n<ol>\n<li>Direct SES API (SendRawEmail) integration \u2014 no SMTP required.<\/li>\n<li>Background sending queue with Action Scheduler or wp_cron fallback.<\/li>\n<li>Tiny-args queueing with job IDs to keep cron payloads small and private.<\/li>\n<li>Configurable rate limiting per second to stay under SES send rate.<\/li>\n<li>From\/Reply-To handling with optional forced From and custom X-* headers.<\/li>\n<li>Test tab to send a test email and a Status tab to fetch SES GetSendQuota.<\/li>\n<li>Logging via WooCommerce logger or PHP error_log, disabled by default.<\/li>\n<li>Credentials from wp-config (constants) or saved settings.<\/li>\n<li>Lightweight, minimal I\/O, no Composer dependency.<\/li>\n<li>Uninstall cleanup toggle to remove settings and queued jobs on deletion.<\/li>\n<\/ol>\n\n<h3>Why It's High Performance<\/h3>\n\n<ul>\n<li>Avoids SMTP for the send path; uses PHPMailer only for MIME construction, then sends via SES API directly.<\/li>\n<li>Background queue returns control to the request immediately when enabled.<\/li>\n<li>Job payloads are stored server-side and referenced by a small <code>job_id<\/code> to avoid large serialized cron arguments.<\/li>\n<li>Logging is optional and disabled by default to keep I\/O low.<\/li>\n<\/ul>\n\n<h3>Configuration<\/h3>\n\n<h3>Credentials in wp-config (recommended)<\/h3>\n\n<p>Define the following constants above \u201cThat\u2019s all, stop editing!\u201d in <code>wp-config.php<\/code>, then enable \u201cRead AWS credentials from wp-config\u201d in the plugin settings.<\/p>\n\n<pre><code>define('SES_MAILER_ACCESS_KEY', 'YOUR_ACCESS_KEY_ID');\ndefine('SES_MAILER_SECRET_KEY', 'YOUR_SECRET_ACCESS_KEY');\ndefine('SES_MAILER_REGION', 'us-east-1');\n<\/code><\/pre>\n\n<p>When this mode is enabled, the Access Key, Secret, and Region fields are cleared, disabled, and ignored.<\/p>\n\n<h3>Background Sending<\/h3>\n\n<ul>\n<li>When enabled, emails are queued and sent out of band by Action Scheduler if available, or by wp_cron as a fallback.<\/li>\n<li>The plugin stores the full email payload in an option keyed by <code>ses_mailer_job_{uuid}<\/code> (autoload = no) and schedules a tiny cron\/action with only <code>job_id<\/code>.<\/li>\n<li>Retries: up to 3 total attempts with exponential backoff (60s, then 120s).<\/li>\n<li>For consistent cron execution on low-traffic sites, configure a real system cron to call <code>wp-cron.php<\/code> regularly.<\/li>\n<\/ul>\n\n<h3>Rate Limiting<\/h3>\n\n<ul>\n<li>A per-email pause is applied based on the configured send rate to avoid exceeding SES limits.<\/li>\n<\/ul>\n\n<h3>Logging<\/h3>\n\n<ul>\n<li>When enabled, log entries route to WooCommerce Status \u2192 Logs (source: api-mailer-for-aws-ses) if WooCommerce is active, or to the PHP error log otherwise.<\/li>\n<li>Logging is disabled by default. Uncheck \"Disable logging\" in settings to enable.<\/li>\n<\/ul>\n\n<h3>External Services<\/h3>\n\n<ul>\n<li>This plugin connects to Amazon Simple Email Service (AWS SES) at <code>https:\/\/email.{region}.amazonaws.com<\/code> to send email and to fetch sending quotas.<\/li>\n<li>Data sent on each email: recipients, subject, message body, headers, attachments, and your AWS access key ID (signed via AWS SigV4); required to deliver the email.<\/li>\n<li>Data sent when checking quotas: your AWS access key ID and a signed request; no recipient data is sent.<\/li>\n<li>Service terms: https:\/\/aws.amazon.com\/service-terms\/ \u2014 Privacy: https:\/\/aws.amazon.com\/privacy\/<\/li>\n<\/ul>\n\n<h3>Translations<\/h3>\n\n<ul>\n<li>Text domain: <code>api-mailer-for-aws-ses<\/code><\/li>\n<li>Translation template: <code>languages\/api-mailer-for-aws-ses.pot<\/code><\/li>\n<li>Example: Danish <code>languages\/api-mailer-for-aws-ses-da_DK.po<\/code> (compile to <code>.mo<\/code> for runtime)<\/li>\n<\/ul>\n\n<h3>About the Author<\/h3>\n\n<p>API Mailer for AWS SES is built and maintained by <a href=\"https:\/\/beltoft.net\">beltoft.net<\/a>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>wp-content\/plugins\/<\/code> or install via the Plugins screen.<\/li>\n<li>Activate the plugin.<\/li>\n<li>Go to Settings \u2192 API Mailer for AWS SES.<\/li>\n<li>Provide AWS credentials and Region in one of two ways:\n\n<ul>\n<li>Saved settings (fields on the Settings screen), or<\/li>\n<li>From wp-config (recommended for production).<\/li>\n<\/ul><\/li>\n<li>Optionally enable background sending and configure rate limit.<\/li>\n<li>Use the Test tab to send a test email.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<p>Q: I get 403 SignatureDoesNotMatch.\nA: Check Access Key\/Secret and ensure the Region matches your SES setup. Verify your \u201cFrom\u201d address is verified in SES.<\/p>\n\n<p>Q: Do test emails appear in Logs?\nA: Yes. Test emails are tagged and logged unless logging is disabled in settings.<\/p>\n\n<p>Q: Do I need Action Scheduler installed?\nA: No. If unavailable, the plugin falls back to wp_cron automatically. A real cron is recommended for consistent processing.<\/p>\n\n<p>Q: Can I keep credentials out of the database?\nA: Yes. Use the wp-config constants and enable \u201cRead AWS credentials from wp-config\u201d.<\/p>\n\n<!--section=changelog-->\n<h4>1.4<\/h4>\n\n<ul>\n<li>New maintainer: beltoft.net.<\/li>\n<li>Security: encrypt secret key at rest (AES-256-CBC), validate attachment paths against uploads\/wp-content only.<\/li>\n<li>Logging: replaced custom file logger with WooCommerce logger (falls back to error_log); removed Logs tab. The old <code>wp-content\/ses-mailer-logs\/<\/code> directory is no longer used and can be safely deleted.<\/li>\n<li>Queue: job persistence checks throughout, retry scheduling failure handling, delete-safe stale job cleanup.<\/li>\n<li>Hardening: autoloader path sanitization, cron dedup lock, proper XML error handling, rate-limit via transients.<\/li>\n<li>Added PHPUnit test suite with WordPress function stubs.<\/li>\n<\/ul>\n\n<h4>1.3<\/h4>\n\n<ul>\n<li>Use PHPMailer (bundled with WordPress) for MIME construction instead of manual MIME building; consistent with FluentSMTP and other major WP mailer plugins.<\/li>\n<li>Auto-detect HTML content when plugins send HTML without explicit Content-Type header.<\/li>\n<li>CC\/BCC support via PHPMailer header parsing (previously silently dropped).<\/li>\n<li>Remove dead <code>SendEmail<\/code> structured API code and manual MIME helpers.<\/li>\n<\/ul>\n\n<h4>1.2<\/h4>\n\n<ul>\n<li>Fix broken plain text generation in background queue (was using <code>wp_strip_all_tags<\/code> instead of <code>html_to_text<\/code>).<\/li>\n<\/ul>\n\n<h4>1.1<\/h4>\n\n<ul>\n<li>Updated text domain to match plugin slug; aligned Action Scheduler group and translation assets.<\/li>\n<li>Documented AWS SES as an external service (data sent, endpoints, terms\/privacy).<\/li>\n<li>Improved log path resolution using uploads directory helpers; removed direct core includes; log clearing uses <code>wp_delete_file<\/code>.<\/li>\n<li>Added Amazon SES setup guide and updated contributors list.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<p>Rename plugin to \u201cAPI Mailer for AWS SES\u201d. Update text domain to <code>api-mailer-for-aws-ses<\/code>, language files, and internal identifiers.<\/p>\n\n<h4>1.0.0<\/h4>\n\n<p>Initial public release.\n- Direct SendRawEmail integration\n- Background queue with Action Scheduler \/ wp_cron\n- Job ID indirection for small cron args\n- Logging viewer with production disable\n- Settings link in plugin list\n- wp-config credential mode<\/p>","raw_excerpt":"Amazon SES API mailer for WordPress that bypasses SMTP and sends via the SES SendRawEmail API with a lightweight, high\u2011performance design.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/252655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=252655"}],"author":[{"embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/beltoftnet"}],"wp:attachment":[{"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=252655"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=252655"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=252655"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=252655"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=252655"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/azb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=252655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}