{"id":341730,"date":"2026-07-21T03:55:48","date_gmt":"2026-07-21T03:55:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/document-expiry-reminder\/"},"modified":"2026-07-21T03:55:15","modified_gmt":"2026-07-21T03:55:15","slug":"document-expiry-reminder","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/document-expiry-reminder\/","author":23533769,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.0","stable_tag":"0.1.0","tested":"7.0.2","requires":"6.5","requires_php":"8.1","requires_plugins":null,"header_name":"Document Expiry Reminder","header_author":"Document Expiry Reminder Contributors","header_description":"Track document expiry dates, assign owners and recipients, and schedule automated reminders. Does not provide legal advice or guarantee regulatory compliance.","assets_banners_color":"","last_updated":"2026-07-21 03:55:15","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":30,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.0":{"tag":"0.1.0","author":"sathsarawj","date":"2026-07-21 03:55:15"}},"upgrade_notice":{"0.1.0":"<p>Initial release candidate. No upgrade path applies yet.<\/p>"},"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.0"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Dashboard \u2014 status summary, upcoming expirations, and cron health.","2":"Documents list \u2014 search, filter by category and status.","3":"Add\/Edit Document \u2014 dates, owner, category, and reminder mode.","4":"Settings \u2014 reminder timing, thresholds, and global rules.","5":"Notifications \u2014 reminder history with retry.","6":"CSV import \u2014 preview before confirming."}},"plugin_section":[],"plugin_tags":[14361,9054,9502,4906,11131],"plugin_category":[],"plugin_contributors":[272560],"plugin_business_model":[],"class_list":["post-341730","plugin","type-plugin","status-publish","hentry","plugin_tags-compliance","plugin_tags-documents","plugin_tags-expiry","plugin_tags-notifications","plugin_tags-reminders","plugin_contributors-sathsarawj","plugin_committers-sathsarawj"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/document-expiry-reminder.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Document Expiry Reminder helps you keep track of documents that expire \u2014\nlicences, certificates, contracts, permits, insurance policies and\nsimilar records \u2014 and reminds the right people before they lapse.<\/p>\n\n<p>This plugin assists with document-expiry tracking and reminders. It does\nnot provide legal advice or guarantee regulatory compliance.<\/p>\n\n<h4>Major features<\/h4>\n\n<ul>\n<li><strong>Document tracking<\/strong> \u2014 title, reference number, category, owner\n(a WordPress user), issue date, expiry date, workflow state, and notes,\nwith a calculated status (Active, Expiring Soon, Critical, Expired, or\nNo Expiry) that recalculates automatically as dates approach.<\/li>\n<li><strong>Automated reminders<\/strong> \u2014 a daily scan sends email reminders on\nconfigurable days-before\/after-expiry offsets, to configurable\nrecipients (site administrator, document owner, or a custom email\naddress), either globally or overridden per document.<\/li>\n<li><strong>Renewal history<\/strong> \u2014 renewing a document records the previous dates\nand file as an immutable history entry; nothing is ever overwritten\nor lost.<\/li>\n<li><strong>Secure file uploads<\/strong> \u2014 attach a scanned copy of a document, stored\noutside the web-servable uploads path and served only to authorized\nusers.<\/li>\n<li><strong>CSV import and export<\/strong> \u2014 bulk-load documents from a spreadsheet, or\nexport the current list, with a preview-before-import safety step.<\/li>\n<li><strong>Role-based access<\/strong> \u2014 an Administrator role and a Document Manager\nrole (everything except plugin settings), built from nine\nindependent capabilities so access can be tuned further if needed.<\/li>\n<li><strong>Notification history<\/strong> \u2014 every reminder ever sent, failed, or\nskipped is recorded and reviewable, with a manual retry action for\nfailures.<\/li>\n<li><strong>Privacy-aware<\/strong> \u2014 integrates with WordPress's built-in personal-data\nexport and erasure tools.<\/li>\n<li><strong>Accessible<\/strong> \u2014 audited against WCAG 2.2 AA (see\ndocs\/ACCESSIBILITY.md in the plugin's source repository).<\/li>\n<li>Deactivating the plugin never deletes your data. Uninstalling it only\ndeletes data if you explicitly opt in beforehand.<\/li>\n<\/ul>\n\n<h4>Who this is for<\/h4>\n\n<p>Anyone tracking documents with a hard expiry date and a real cost of\nmissing it: compliance certificates, professional licences, insurance\npolicies, contracts, permits, domain\/SSL-adjacent internal records, or\nsimilar. It is a WordPress-native alternative to a spreadsheet with a\nmanually-checked \"renew by\" column.<\/p>\n\n<h3>Configuration<\/h3>\n\n<p>All configuration lives on Document Expiry \u2192 Settings:<\/p>\n\n<ul>\n<li><strong>Expiring soon days \/ Critical days<\/strong> \u2014 how many days before expiry a\ndocument is considered \"expiring soon\" or \"critical\", for the\ncalculated status shown throughout the admin.<\/li>\n<li><strong>Reminder processing time<\/strong> \u2014 the time of day (in your site's\nconfigured timezone) the daily reminder scan runs.<\/li>\n<li><strong>Batch size<\/strong> \u2014 the maximum number of reminder emails sent per\nprocessing run, to bound how long any one run takes.<\/li>\n<li><strong>Global reminder rules<\/strong> \u2014 one or more \"N days before\/after expiry,\nsend to X\" rules that apply to every document left on the default\n\"inherit\" reminder mode. Individual documents can instead be given\ntheir own document-specific rules, or have reminders disabled\nentirely.<\/li>\n<li><strong>File uploads<\/strong> \u2014 enable\/disable, maximum size, and allowed file\nextensions.<\/li>\n<li><strong>Email sender name \/ reply-to<\/strong> \u2014 used on outgoing reminder emails.<\/li>\n<li><strong>Delete data on uninstall<\/strong> \u2014 off by default; see \"Privacy\" below.<\/li>\n<\/ul>\n\n<p>All dates entered anywhere in the plugin are interpreted, calculated,\nand displayed in your site's configured timezone (Settings \u2192 General \u2192\nTimezone in WordPress core), not UTC and not the server's local time.<\/p>\n\n<p>See <code>docs\/ADMIN-GUIDE.md<\/code> in the plugin's source repository for a full\nwalkthrough of every screen.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>This plugin stores documents, categories, reminder rules, renewal\nhistory, uploaded files, and notification records in its own database\ntables. The only personal data involved is the association between a\ndocument and its \"owner\" (a WordPress user) and the recipient email\naddresses reminder notifications were sent to.<\/p>\n\n<ul>\n<li>It registers <code>wp_add_privacy_policy_content()<\/code> suggested policy text.<\/li>\n<li>It supports WordPress's built-in \"Export Personal Data\" tool for a\ndocument owner's associated documents.<\/li>\n<li>It supports WordPress's built-in \"Erase Personal Data\" tool: erasing a\nuser anonymizes their <code>owner_user_id<\/code> reference on documents (the\ndocuments themselves, and their history, are never deleted by an\nerasure request \u2014 only the personal-data linkage is removed).<\/li>\n<li>It makes no external network calls and uses no third-party analytics,\nadvertising, or tracking service of any kind.<\/li>\n<li>Deactivating never deletes data. Uninstalling only deletes data if you\nhave explicitly opted in via Settings beforehand.<\/li>\n<\/ul>\n\n<h3>Support<\/h3>\n\n<p>Please use the plugin's WordPress.org support forum for questions.\nInclude your WordPress version, PHP version, and (if reporting a bug) the\nsteps to reproduce it and any relevant error messages \u2014 never include\nreal document contents, email addresses, or other personal data in a\npublic support request.<\/p>\n\n<h3>License<\/h3>\n\n<p>This plugin is licensed under the GPLv2 (or later). See\nhttps:\/\/www.gnu.org\/licenses\/gpl-2.0.html for the full license text.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to the <code>\/wp-content\/plugins\/<\/code> directory, or install\nit through the WordPress \"Add New Plugin\" screen (Plugins \u2192 Add New \u2192\nUpload Plugin).<\/li>\n<li>Activate the plugin through the \"Plugins\" screen in WordPress.\nActivation creates the plugin's database tables and the\n\"Document Manager\" role; it never modifies any other plugin's or\nWordPress core's data.<\/li>\n<li>A new \"Document Expiry\" menu appears in the admin sidebar. Start on\nits Settings screen to configure reminder timing, thresholds, and\nrecipients (see \"Configuration\" below), then add your first document\nfrom Document Expiry \u2192 Add New.<\/li>\n<\/ol>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>WordPress 6.5 or later.<\/li>\n<li>PHP 8.1 or later.<\/li>\n<li>Outbound email configured on the server (or an SMTP plugin) for\nreminders to actually leave the server \u2014 see \"Email delivery\" below.<\/li>\n<li>If using file uploads: a hosting environment where a\nnon-web-servable directory can be created under <code>wp-content\/uploads\/<\/code>\n\u2014 see \"Secure upload requirements\" below.<\/li>\n<\/ul>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20guarantee%20legal%20or%20regulatory%20compliance%3F\"><h3>Does this plugin guarantee legal or regulatory compliance?<\/h3><\/dt>\n<dd><p>No. This plugin assists with document-expiry tracking and reminders. It\ndoes not provide legal advice or guarantee regulatory compliance. You\nremain responsible for verifying your own compliance obligations.<\/p><\/dd>\n<dt id=\"does%20deactivating%20the%20plugin%20delete%20my%20data%3F\"><h3>Does deactivating the plugin delete my data?<\/h3><\/dt>\n<dd><p>No. Deactivation never deletes data. Data is only removed on uninstall\n(deleting the plugin after deactivating it), and only if you have\nexplicitly enabled \"Delete data on uninstall\" in Settings beforehand. By\ndefault, uninstalling also preserves all data.<\/p><\/dd>\n<dt id=\"does%20a%20%22sent%22%20notification%20mean%20the%20email%20was%20actually%20delivered%3F\"><h3>Does a \"Sent\" notification mean the email was actually delivered?<\/h3><\/dt>\n<dd><p>No. \"Sent\" means WordPress's <code>wp_mail()<\/code> function accepted the message\nfor processing and reported success \u2014 it does not mean the message was\ndelivered to, or arrived in, the recipient's inbox. Actual delivery\ndepends on your server's mail transport, DNS\/SPF\/DKIM configuration, and\nthe receiving mail server, none of which this plugin controls or can\nverify. If reminders are not arriving, check your site's outbound-email\nconfiguration (an SMTP plugin is strongly recommended over PHP's default\n    mail() function) and the Notifications screen for recorded failures.<\/p><\/dd>\n<dt id=\"why%20didn%27t%20my%20reminder%20send%20exactly%20on%20schedule%3F\"><h3>Why didn't my reminder send exactly on schedule?<\/h3><\/dt>\n<dd><p>By default, WordPress uses WP-Cron, which only fires on a site visit \u2014\non a low-traffic site, a scheduled event can run late. For reliable\ntiming, configure a real system cron job to trigger WordPress's\nscheduler instead of relying on site traffic. See <code>docs\/CRON-SETUP.md<\/code>\nin the plugin's source repository for exact instructions. The\nNotifications screen shows a warning if scheduling looks unhealthy or\nstale.<\/p><\/dd>\n<dt id=\"what%20are%20the%20server%20requirements%20for%20secure%20file%20uploads%3F\"><h3>What are the server requirements for secure file uploads?<\/h3><\/dt>\n<dd><p>Uploaded files are stored in a dedicated directory\n(<code>wp-content\/uploads\/document-expiry-reminder-private\/<\/code>) that must not\nbe directly reachable by URL \u2014 files are only ever served through the\nplugin's own authenticated download handler. The plugin attempts to\nverify this automatically and warns in the admin if it cannot confirm\nprotection. On Apache, this typically requires directory listing and\ndirect access to be disabled (an <code>.htaccess<\/code> file, generated\nautomatically, handles this in most configurations); on Nginx, a\nmatching server-block rule needs to be added manually. See\n    docs\/FILE-STORAGE-SETUP.md in the plugin's source repository for exact\nconfiguration examples.<\/p><\/dd>\n<dt id=\"where%20do%20i%20report%20a%20bug%20or%20request%20a%20feature%3F\"><h3>Where do I report a bug or request a feature?<\/h3><\/dt>\n<dd><p>Through the plugin's support forum on WordPress.org, or the issue\ntracker of its source repository if you installed it from source\ncontrol.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.0<\/h4>\n\n<p>Initial release candidate. See CHANGELOG.md in the plugin's source\nrepository for the full, itemized list of what this version includes.<\/p>","raw_excerpt":"Track document expiry dates, assign owners and recipients, and send automated renewal reminders.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/341730","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=341730"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sathsarawj"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=341730"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=341730"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=341730"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=341730"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=341730"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=341730"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}